Grpc快速实践
Posted 悟初境
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Grpc快速实践相关的知识,希望对你有一定的参考价值。
记录下Grpc使用,从 grpc maven编译插件到客户端服务端实现。
proto和Service定义
src/main/proto/AgentModel.proto
模型定义2个实体,参数和返回值。
syntax = "proto3";
option java_package = "com.jimo.grpc";
message AgentInfo
string name = 1;
sint32 index = 2;
message ReportResponse
bool ok = 1;
string msg = 2;
src/main/proto/AgentService.proto
在服务这边就定义一个report方法。
syntax = "proto3";
option java_package = "com.jimo.grpc";
import "AgentModel.proto";
service Agent
rpc report(AgentInfo) returns (ReportResponse)
编译
加入maven插件,同时编译proto文件和grpc。
<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.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:$protoc.version:exe:$os.detected.classifier
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:$grpc.version:exe:$os.detected.classifier
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
假如要用离线的proto执行文件,可以换成本地路径:
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocExecutable>D:\\software\\protoc.exe</protocExecutable>
<pluginId>grpc-java</pluginId>
<pluginExecutable>D:\\software\\protoc-gen-grpc-java.exe</pluginExecutable>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
在命令行运行 mvn compile 可编译出protobuf和grpc的类,结构如下:
└─target
├─generated-sources
│ ├─annotations
│ └─protobuf
│ ├─grpc-java
│ │ └─com
│ │ └─jimo
│ │ └─grpc
│ │ AgentGrpc.java
│ │
│ └─java
│ └─com
│ └─jimo
│ └─grpc
│ AgentModel.java
│ AgentService.java
服务端实现
先实现服务的处理逻辑: AgentServiceImpl 继承 GRPC生成的抽象类。
import com.jimo.grpc.AgentGrpc;
import com.jimo.grpc.AgentModel;
import io.grpc.stub.StreamObserver;
public class AgentServiceImpl extends AgentGrpc.AgentImplBase
@Override
public void report(AgentModel.AgentInfo request, StreamObserver<AgentModel.ReportResponse> responseObserver)
AgentModel.ReportResponse response = AgentModel.ReportResponse.newBuilder().setOk(true).setMsg(request.getName()).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
然后起一个服务:
public static void main(String[] args) throws IOException, InterruptedException
Server server = ServerBuilder.forPort(8000)
.addService(new AgentServiceImpl())
.build().start();
Runtime.getRuntime().addShutdownHook(new Thread(() ->
try
server.shutdown().awaitTermination(10, TimeUnit.SECONDS);
catch (InterruptedException e)
e.printStackTrace();
));
System.out.println("Listening on 8000...");
server.awaitTermination();
客户端实现
客户端一般共用一个 Channel,所以传进来.然后通过 Stub调用。
import com.jimo.grpc.AgentGrpc;
import com.jimo.grpc.AgentModel;
import io.grpc.Channel;
public class AgentClient
private final AgentGrpc.AgentBlockingStub stub;
public AgentClient(Channel channel)
stub = AgentGrpc.newBlockingStub(channel);
public void report()
AgentModel.ReportResponse res = stub.report(AgentModel.AgentInfo.newBuilder().setName("app01").setIndex(98).build());
System.out.println("收到回复:" + res);
客户端共用一个 Channel的创建和调用:
public static void main(String[] args) throws InterruptedException
// channel最好创建一个,可以共用,是线程安全的
ManagedChannel channel = ManagedChannelBuilder
.forAddress("localhost", 8000)
// 默认是SSL/TLS,这里不用
.usePlaintext()
.build();
AgentClient agentClient = new AgentClient(channel);
agentClient.report();
agentClient.report();
// channel默认会等待一段时间关闭,如果不用了最好及时关闭,否则会占用TCP连接
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
更多问题
1、我们需要对请求做拦截,做一些AOP的事情怎么弄?—-用 ClientInterceptor
2、在上面的客户端使用了 AgentGrpc.newBlockingStub(channel),还有好几种Stub,有什么区别,怎么使用?
3、客户端和服务端通信的网络和协议是如何实现的?为什么客户端的Channel会自动关闭?
先把坑埋好。
以上是关于Grpc快速实践的主要内容,如果未能解决你的问题,请参考以下文章