一.入门基本rpc 1.首先需要导入我们需要的包,pom文件中加入
io.grpc
grpc-netty-shaded
${grpc.version}
io.grpc
grpc-protobuf
${grpc.version}
io.grpc
grpc-stub
${grpc.version}
基于protobuf文件代码生成的插件
kr.motd.maven
os-maven-plugin
1.5.0.Final
org.xolstice.maven.plugins
protobuf-maven-plugin
0.5.1
com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}grpc-javaio.grpc:protoc-gen-grpc-java:1.21.0:exe:${os.detected.classifier}
compile
compile-custom
2.编写proto文件
//使用proto3语法
syntax = "proto3";
import "google/protobuf/wrappers.proto";
//代码生成的路径
option java_multiple_files = true;
option java_package = "com.thundersdata.backend.facade.grpc";
//service及里面开发的rpc方法
service GreeterService {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayTest(google.protobuf.Int32Value) returns (google.protobuf.Int32Value) {}
rpc SayQlu(google.protobuf.StringValue) returns (google.protobuf.StringValue){}
}message HelloRequest {
string name = 1;
int32 age = 2;
}message HelloReply {
string message = 1;
}
使用pom文件中加入的插件生成代码。
mvn package的话也会自动生成。
3.编写服务端,开放proto文件中定义的rpc方法,并实现方法的内部逻辑,然后开启服务监听客户端请求。
编写开发rpc方法代码,实现我们服务定义的生成的服务接口。
StreamObserver responseObserver 是一个应答的观察者,实际上是服务器调用它应答的一个特殊接口。
- 我们使用应答观察者的
onNext()
方法返回结果。 - 我们使用应答观察者的
onCompleted()
方法来指出我们已经完成了和 RPC的交互。
@Service
public class GreeterServiceImpl extends GreeterServiceGrpc.GreeterServiceImplBase implements GreeterService {public void sayHello(HelloRequest req, StreamObserver responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage(("Hello: " + req.getName())).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}public void sayTest(Int32Value id, StreamObserver responseObserver) {
responseObserver.onNext(id);
responseObserver.onCompleted();
}public void sayQlu(StringValue request, StreamObserver responseObserver) {
responseObserver.onNext(request);
responseObserver.onCompleted();
}public String sayHello(String hello){
return hello;
}
}
开启服务,监听客户端的请求。
- 使用构建器的
forPort()
方法指定我们要用于侦听客户端请求的地址和端口。 - 创建我们的服务实现类的实例
RouteGuideService
并将其传递给构建器的addService()
方法。 - 调用
build()
并start()
在构建器上为我们的服务创建和启动RPC服务器
@Component
public class ServiceServer {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${grpc.port}")
private int port;
@Autowired
private GreeterServiceImpl greeterService;
private Server server;
public void start() {
try{
server = ServerBuilder.forPort(port)
.addService(greeterService)
.build()
.start();
logger.info("grpc service start with port {}...", port);
}catch (IOException e){
e.printStackTrace();
}Runtime.getRuntime().addShutdownHook(new Thread() {@Override
public void run() {System.err.println("*** shutting down gRPC server since JVM is shutting down");
ServiceServer.this.stop();
System.err.println("*** server shut down");
}
});
}private void stop() {
if (server != null) {
server.shutdown();
}
}// block 一直到退出程序
public void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
}
4.编写客户端,使用存根访问开放的rpc方法。
创建存根
为了调用服务方法,我们需要首先创建一个 存根,或者两个存根:
- 一个 阻塞/同步 存根:这意味着 RPC 调用等待服务器响应,并且要么返回应答,要么造成异常。
- blockingStub = RouteGuideGrpc.newBlockingStub(channel);
- 一个 非阻塞/异步 存根可以向服务器发起非阻塞调用,应答会异步返回。你可以使用异步存根去发起特定类型的流式调用。
- asyncStub = RouteGuideGrpc.newStub(channel);
@Data
public class BasicClient {private final ManagedChannel channel;
private final GreeterServiceGrpc.GreeterServiceBlockingStub greeterService;
public BasicClient(String host, int port) {
channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build();
greeterService = GreeterServiceGrpc.newBlockingStub(channel);
}}
5.调用
greeterService = basicClient.getGreeterService();
@Test
public void helloTest() {
HelloRequest helloRequest = HelloRequest.newBuilder().setAge(20).setName("xiaoming").build();
HelloReply helloReply = greeterService.sayHello(helloRequest);
Assert.assertEquals("Hello: xiaoming", helloReply.getMessage());
}
和正常方法调用没有很大区别
附学习网站:
官网:https://grpc.io/docs/tutorials/basic/java/
http://grpc.mydoc.io/?t=60134
【Spring|GRPC学习笔记】对复杂属性list,map的处理https://blog.csdn.net/July_whj/article/details/79423459
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- =======j2ee|spring用注解实现注入的@resource,@autowired,@inject区别
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])