RPC框架实践之:Google gRPC


声明:本文转载自https://my.oschina.net/hansonwang99/blog/1815743,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

My Desktop

My Desktop


概述

gRPC是Google开源的通用高性能RPC框架,它支持的是使用Protocol Buffers来编写Service定义,支持较多语言扩平台并且拥有强大的二进制序列化工具集。与文章《RPC框架实践之:Apache Thrift》 一文中实践的另一种通用RPC框架 Thrift 能通过Generator自动生成对应语言的Service接口类似,gRPC也能 自动地生成 Server和Client的 Service存根(Stub),我们只需要 一个命令 就能快速搭建起RPC运行环境。

下面实践一下gRPC框架,做的事情就是:Client端通过远程RPC调用Server的获取时间的接口,从而将服务器时间获取到本地并显示。

类似于之前对于 RPC框架: Thrift 的实践步骤,下面一一阐述。


开发gRPC-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 等等

与grpc相关的包

  • pom中加入grpc相关的 build插件

这里添加两个Maven插件,目的是后面需要用这些插件来执行Protocol Buffers命令,从而自动生成相关的Stub代码:

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的服务定义文件

这里.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 compile命令来自动生成代码Stub

mvn编译完成以后,在target/generated-sources目录下就能看到根据上面.proto文件自动转化生成的Java代码Stub

mvn编译

代码生成结果如下所示

代码生成结果

好了,既然gRPC-API已经有了,下面可以分别编写服务端和客户端


开发gRPC服务端

  • 创建基于Maven的项目:Server

  • pom中添加 GrpcAPI 依赖

        <dependency>             <groupId>com.hansonwang99</groupId>             <artifactId>GrpcAPI</artifactId>             <version>1.0-SNAPSHOT</version>             <scope>compile</scope>         </dependency> 

接下来一步比较关键

  • 实现gRPC服务接口
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字段进行拼接,然后返回给调用端!形成一个闭环

  • 创建gRPC服务端启动类
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,来启动服务端

启动服务端


开发gRPC客户端

  • 创建基于Maven的项目:Client

  • pom中依然需要添加 GrpcAPI 依赖

        <dependency>             <groupId>com.hansonwang99</groupId>             <artifactId>GrpcAPI</artifactId>             <version>1.0-SNAPSHOT</version>             <scope>compile</scope>         </dependency> 
  • 创建gRPC客户端启动类
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!


C-S通信实验

还记得我们的目标吗?

RPC完成的即是远程的过程调用,在本实验中那就是客户端可以远程调用服务端的getDate()过程,并将结果取到客户端来显示!

RPC调用成功


后记

本文实验代码在码云 → 需要自取

作者更多的原创文章:在开源中国

作者其他一些RPC框架的实践如下:

作者一些关于容器化、微服务化方面的文章如下:


本文发表于2018年05月21日 06:00
(c)注:本文转载自https://my.oschina.net/hansonwang99/blog/1815743,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2004 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1