GRPC实现服务通信
grpc相关特性:
gRPC 是一种现代开源高性能远程过程调用 (RPC) 框架,可以在任何环境中运行。它可以通过对负载平衡、跟踪、健康检查和身份验证的可插拔支持,有效地连接数据中心内和数据中心之间的服务。它还适用于分布式计算的最后一英里,将设备、移动应用程序和浏览器连接到后端服务。特性如下:
1.简单的服务定义
使用 Protocol Buffers 定义您的服务,这是一种强大的二进制序列化工具集和语言。
2.快速启动并扩展
使用一行代码安装运行时和开发环境,并使用框架扩展到每秒数百万次 RPC。
3.跨语言和平台工作
以各种语言和平台为您的服务自动生成惯用的客户端和服务器存根。
4.双向流和集成身份验证
双向流和完全集成的可插拔身份验证与基于 HTTP/2 的传输。
grpc与protobuf是相辅相成的,想要使用grpc,必须先学会使用protobuf,grpc跨语言和平台工作的能力是protobuf赋予的。但是利用传统的protobuf的生成器,反而不能生成grpc的代码,java语言有专门的grpc的代码生成的maven插件。如果你想了解protobuf,可以参考:https://www.jianshu.com/p/a24c88c0526a
1、定义proto文件
在main文件夹下新建proto文件夹,在proto文件夹下新建.proto文件
syntax = "proto3";
package com.redic.Test;//编译后包的位置
option java_multiple_files = true; //拆分成多个文件
//请求对象
message inpushRequest{
string name = 1;
string msg = 2;
int32 i = 3;
}
//返回对象
message ReturnResponse{
Result result = 1;
string msg = 2;
}
enum Result {
SUCCESS = 0;
FAIL = 1;
}
//接口
service TestService{
//方法
rpc getInpushService(inpushRequest) returns (ReturnResponse);
}
2、整合Grpc所需要的Maven插件
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>1.17.1</version>
<exclusions>
<exclusion>
<artifactId>netty-common</artifactId>
<groupId>io.netty</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
<version>4.1.14.Final</version>
</dependency>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.3.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.17.1:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
注:记住在你的各个服务一定要公共模块
<dependency>
<groupId>com.redic</groupId>
<artifactId>cloud-api-common</artifactId>
<version>${project.version}</version>
</dependency>
3、通过插件生成接口代码
编译好后,就会自动在target中出现生成好的代码文件,在.proto定义的 package com.redic.Test 文件夹下面
4、服务端业务实现代码
4.1 yml文件配置服务端
grpc:
server:
port: 50001
4.1 业务代码
@GrpcService
@Slf4j
public class TestService extends TestServiceGrpc.TestServiceImplBase {
/**
* server实现代码
* @param request
* @param responseObserver
*/
@Override
public void getInpushService(inpushRequest request, StreamObserver<ReturnResponse> responseObserver) {
ReturnResponse response = null;
try {
log.info("name:"+request.getName());
log.info("msg:"+request.getMsg());
response = ReturnResponse.newBuilder()
.setMsg("测试成功了!")
.setResult(Result.SUCCESS)
.build();
} catch (Exception e) {
e.printStackTrace();
response = ReturnResponse.newBuilder()
.setResult(Result.FAIL)
.build();
} finally {
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
}
5、客户端业务实现代码
5.1 yml文件配置客户端
grpc:
client:
test-grpc-server:
address: static://localhost:50001
# enableKeepAlive: true
# keepAliveWithoutCalls: true
negotiationType: plaintext
5.1 实现客户端
@Slf4j
@Component
public class TestClient {
@GrpcClient("test-grpc-server")
private TestServiceGrpc.TestServiceBlockingStub testServiceBlockingStub;
public void inpush(){
try {
inpushRequest request = inpushRequest.newBuilder()
.setName("向大阳")
.setMsg("测试了一下")
.build();
ReturnResponse response = testServiceBlockingStub.withDeadlineAfter(5, TimeUnit.SECONDS).getInpushService(request);
if(response.getResult().getNumber() == 1){
log.info(response.getMsg());
}else {
log.info(response.getMsg());
}
} catch (Exception e) {
e.printStackTrace();
throw new CustomException(e.getMessage());
}
}
}
6、测试
测试代码就不写了,只展示测试结果:
服务端:
客户端:
到这里,就算是成功了,自己动手试试吧