阅读:58
说明:
GRPC是什么?
首先我们知道 RPC是远程过程调用。
而GRPC是RPC的一种实现。
那么为什么要用GRPC呢?
因为它支持跨语言的开发,换句话说,大家都用过FeignRPC,尤其在spring cloud中。
然而它只支持java语言,而作为微服务,可能有很多其他的服务不是java开发的。因此需要满足这个需求,就需要一个跨语言的RPC,所以就会考虑使用GRPC
好了,下面进入正题
直接上代码。
我们做一个Service和一个Client 进行交互。
1,POM
注意:
grpc-spring-boot-starter
os-maven-plugin
protobuf-maven-plugin
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.leadtrans</groupId>
<artifactId>report</artifactId>
<version>1.6.0</version>
<name>report</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
<!-- GRPC -->
<grpc-spring-boot-starter.version>2.3.2</grpc-spring-boot-starter.version>
<os-maven-plugin.version>1.6.0</os-maven-plugin.version>
<protobuf-maven-plugin.version>0.5.1</protobuf-maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
<!-- GRPC -->
<dependency>
<groupId>org.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>${grpc-spring-boot-starter.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<extensions>
<!-- os-maven-plugin -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${os-maven-plugin.version}</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<!-- protobuf-maven-plugin -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>${protobuf-maven-plugin.version}</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.11.0:exe:${os.detected.classifier}</pluginArtifact>
<outputDirectory>${project.build.sourceDirectory}</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2,创建Proto
PS:Proto文件夹,必须和JAVA同级!
HelloWorld.protp
PS:请使用 option java_package="xxxx",
而不是 package xxxx
package xxxx 会导致你引用其他包时,会报错
syntax = "proto3";
option java_multiple_files = true;
option java_package="com.example.test.helloworld";
//请求
message Request {
double num1 = 1;
double num2 = 2;
OperateType opType = 3;
}
//操作类型
enum OperateType {
Addition = 0;
Division = 1;
Multiplication = 2;
Subtraction = 3;
}
message Response {
double result = 1;
}
//定义服务
service Operate {
rpc Calculate (Request) returns (Response);
}
3,执行命令,生成文件
mvn clean install
或者点击
可以看到生成了文件:
4,实现接口
为了简单演示,这里就直接设置Response.Result=2
OperateImpl
@GRpcService
public class OperateImpl extends OperateGrpc.OperateImplBase {
@Override
public void calculate(Request request,
StreamObserver<Response> responseObserver) {
Response response=Response.newBuilder().setResult(2).build();
System.out.println(response);
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
1,POM(同Service端)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>test1</artifactId>
<version>1.0</version>
<name>test1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.0</spring-cloud.version>
<grpc-spring-boot-starter.version>2.3.2</grpc-spring-boot-starter.version>
<os-maven-plugin.version>1.6.0</os-maven-plugin.version>
<protobuf-maven-plugin.version>0.5.1</protobuf-maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- grpc -->
<dependency>
<groupId>org.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>${grpc-spring-boot-starter.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<!-- os-maven-plugin -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${os-maven-plugin.version}</version>
</extension>
</extensions>
<plugins>
<!-- spring-boot-maven-plugin -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- protobuf-maven-plugin -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>${protobuf-maven-plugin.version}</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.11.0:exe:${os.detected.classifier}</pluginArtifact>
<outputDirectory>${project.build.sourceDirectory}</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2,拷贝Proto
和java同级目录
3,执行命令
mvn clean install
4,调用方法
CalculateService
其中 main方法,是测试方法。
GRPC启动的默认端口是6565,在main中设置了。
public class CalculateService {
private final ManagedChannel channel;
private final OperateGrpc.OperateBlockingStub blockingStub;
private CalculateService(ManagedChannel channel) {
this.channel = channel;
blockingStub = OperateGrpc.newBlockingStub(channel);
}
public CalculateService(String host, int port) {
this(ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build());
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public float operate(float num1, float num2, OperateType operateType) {
Request request = Request.newBuilder().setNum1(num1).setNum2(num2).setOpType(operateType).build();
Response response = blockingStub.calculate(request);
return (float) response.getResult();
}
public static void main(String[] args) {
try {
CalculateService service = new CalculateService("localhost", 6565);
System.out.println(service.operate(100, 0, OperateType.Division));
service.shutdown();
} catch (Exception e) {
System.out.println(e);
}
}
}