gRPC是Google开源的通用高性能RPC框架,它支持的是使用Protocol Buffers来编写Service定义,支持较多语言扩平台而且拥有强大的二进制序列化工具集。与文章《RPC框架实践之:Apache Thrift》 一文中实践的另外一种通用RPC框架 Thrift 能经过Generator自动生成对应语言的Service接口相似,gRPC也能 自动地生成 Server和Client的 Service存根(Stub),咱们只须要 一个命令 就能快速搭建起RPC运行环境。java
下面实践一下gRPC框架,作的事情就是:Client端经过远程RPC调用Server的获取时间的接口,从而将服务器时间获取到本地并显示。git
相似于以前对于 RPC框架: Thrift 的实践步骤,下面一一阐述。api
首先建立一个基于Maven的项目: GrpcAPI服务器
pom中加入grpc相关的依赖框架
<dependency> <groupId>io.grpc</groupId> <artifactId>grpc-all</artifactId> <version>1.12.0</version> </dependency>
这个grpc-all包含了不少grpc相关的组件:grpc-netty 、 grpc-protobuf 、grpc-stub 等等maven
这里添加两个Maven插件,目的是后面须要用这些插件来执行Protocol Buffers命令,从而自动生成相关的Stub代码:ide
os-maven-plugin:生成平台无关的属性 protobuf-maven-plugin:执行Protocol Buffers命令并生成Stub代码库微服务
<build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.4.1.Final</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.5.0</version> <configuration> <pluginId>grpc-java</pluginId> <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.2.0:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
这里.proto文件的做用和写法就和个人前一篇文章《RPC框架实践之:Apache Thrift》 一文中Thrift所要求的.thrift文件编写同样,是有其本身的语法要求的!工具
syntax = "proto3”; // 语法版本 // stub选项 option java_package = "com.hansonwang99.grpc.api”; option java_outer_classname = “RPCDateServiceApi”; option java_multiple_files = true; // 定义包名,相似于个人文章《RPC框架实践之:Apache Thrift》中的Thrift的namespace package com.hansonwang99.grpc.api; // 服务接口定义,服务端和客户端都要遵照该接口进行通讯 service RPCDateService { rpc getDate (RPCDateRequest) returns (RPCDateResponse) {} } // 定义消息(请求) message RPCDateRequest { string userName = 1; } // 定义消息(响应) message RPCDateResponse { string serverDate = 1; }
mvn编译完成之后,在 target/generated-sources目录下就能看到根据上面 .proto文件自动转化生成的 Java代码Stub性能
代码生成结果以下所示
好了,既然gRPC-API已经有了,下面能够分别编写服务端和客户端
建立基于Maven的项目:Server
pom中添加 GrpcAPI 依赖
<dependency> <groupId>com.hansonwang99</groupId> <artifactId>GrpcAPI</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope> </dependency>
接下来一步比较关键
public class RPCDateServiceImpl extends RPCDateServiceGrpc.RPCDateServiceImplBase{ @Override public void getDate(RPCDateRequest request, StreamObserver<RPCDateResponse> responseObserver) { RPCDateResponse rpcDateResponse = null; Date now=new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("今天是"+"yyyy年MM月dd日 E kk点mm分”); String nowTime = simpleDateFormat.format( now ); try { rpcDateResponse = RPCDateResponse .newBuilder() .setServerDate( "Welcome " + request.getUserName() + ", " + nowTime ) .build(); } catch (Exception e) { responseObserver.onError(e); } finally { responseObserver.onNext( rpcDateResponse ); } responseObserver.onCompleted(); } }
我想此处重写的 getDate()方法并不陌生吧,这正是上文 .proto 文件中定义的Service接口。 此处逻辑比较简单:获取当前时间,而且将其与请求 RPCDateRequest中提取出的 userName字段进行拼接,而后返回给调用端!造成一个闭环
public class GRPCServer { private static final int port = 9999; public static void main( String[] args ) throws Exception { Server server = ServerBuilder. forPort(port) .addService( new RPCDateServiceImpl() ) .build().start(); System.out.println( "grpc服务端启动成功, 端口=" + port ); server.awaitTermination(); } }
端口自定义的9999,也就是在该端口监听。如今能够当即运行GRPCServer,来启动服务端
建立基于Maven的项目:Client
pom中依然须要添加 GrpcAPI 依赖
<dependency> <groupId>com.hansonwang99</groupId> <artifactId>GrpcAPI</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope> </dependency>
public class GRPCClient { private static final String host = “localhost”; private static final int serverPort = 9999; public static void main( String[] args ) throws Exception { ManagedChannel managedChannel = ManagedChannelBuilder.forAddress( host, serverPort ).usePlaintext().build(); try { RPCDateServiceGrpc.RPCDateServiceBlockingStub rpcDateService = RPCDateServiceGrpc.newBlockingStub( managedChannel ); RPCDateRequest rpcDateRequest = RPCDateRequest .newBuilder() .setUserName(“hansonwang99”) .build(); RPCDateResponse rpcDateResponse = rpcDateService.getDate( rpcDateRequest ); System.out.println( rpcDateResponse.getServerDate() ); } finally { managedChannel.shutdown(); } } }
如今当即启动 GRPCClient!
还记得咱们的目标吗?
RPC完成的便是远程的过程调用,在本实验中那就是客户端能够远程调用服务端的getDate()过程,并将结果取到客户端来显示!
本文实验代码在此 → 须要自取:https://gitee.com/hansonwang99/Maven_gRPC
做者其余一些RPC框架的实践以下:
做者一些关于容器化、微服务化方面的文章以下:
微服务调用链追踪中心搭建
利用K8S技术栈打造我的私有云连载文章
Docker容器可视化监控中心搭建
利用ELK搭建Docker容器化应用日志中心
做者更多 务实、能看懂、可复现的 原创文章尽在公众号 CodeSheep