RPC框架实践之:Google gRPC

Posted CodeSheep

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RPC框架实践之:Google gRPC相关的知识,希望对你有一定的参考价值。


概述

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

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

类似于之前对于  的实践步骤,下面一一阐述。


开发gRPC-API

  • 首先创建一个基于Maven的项目: GrpcAPI

  • pom中加入grpc相关的依赖

 
   
   
 
  1.        <dependency>

  2.            <groupId>io.grpc</groupId>

  3.            <artifactId>grpc-all</artifactId>

  4.            <version>1.12.0</version>

  5.        </dependency>

这个grpc-all包含了很多grpc相关的组件:grpc-netty 、 grpc-protobuf 、grpc-stub 等等

RPC框架实践之:Google gRPC

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

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

os-maven-plugin:生成平台无关的属性 protobuf-maven-plugin:执行Protocol Buffers命令并生成Stub代码库

 
   
   
 
  1.    <build>

  2.        <extensions>

  3.            <extension>

  4.                <groupId>kr.motd.maven</groupId>

  5.                <artifactId>os-maven-plugin</artifactId>

  6.                <version>1.4.1.Final</version>

  7.            </extension>

  8.        </extensions>

  9.        <plugins>

  10.            <plugin>

  11.                <groupId>org.xolstice.maven.plugins</groupId>

  12.                <artifactId>protobuf-maven-plugin</artifactId>

  13.                <version>0.5.0</version>

  14.                <configuration>

  15.                    <pluginId>grpc-java</pluginId>

  16.                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>

  17.                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.2.0:exe:${os.detected.classifier}</pluginArtifact>

  18.                </configuration>

  19.                <executions>

  20.                    <execution>

  21.                        <goals>

  22.                            <goal>compile</goal>

  23.                            <goal>compile-custom</goal>

  24.                        </goals>

  25.                    </execution>

  26.                </executions>

  27.            </plugin>

  28.        </plugins>

  29.    </build>

  • 编写.proto的服务定义文件

这里.proto文件的作用和写法就和我的前一篇文章 一文中Thrift所要求的.thrift文件编写一样,是有其自己的语法要求的!

 
   
   
 
  1. syntax = "proto3”;   // 语法版本

  2. // stub选项

  3. option java_package = "com.hansonwang99.grpc.api”;

  4. option java_outer_classname = RPCDateServiceApi”;

  5. option java_multiple_files = true;

  6. // 定义包名,类似于我的文章《RPC框架实践之:Apache Thrift》中的Thrift的namespace

  7. package com.hansonwang99.grpc.api;

  8. // 服务接口定义,服务端和客户端都要遵守该接口进行通信

  9. service RPCDateService {

  10.  rpc getDate (RPCDateRequest) returns (RPCDateResponse) {}

  11. }

  12. // 定义消息(请求)

  13. message RPCDateRequest {

  14.  string userName = 1;

  15. }

  16. // 定义消息(响应)

  17. message RPCDateResponse {

  18.  string serverDate = 1;

  19. }

  • 执行 mvn compile命令来自动生成代码Stub

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

RPC框架实践之:Google gRPC

代码生成结果如下所示

RPC框架实践之:Google gRPC

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


开发gRPC服务端

  • 创建基于Maven的项目:Server

  • pom中添加 GrpcAPI 依赖

 
   
   
 
  1.        <dependency>

  2.            <groupId>com.hansonwang99</groupId>

  3.            <artifactId>GrpcAPI</artifactId>

  4.            <version>1.0-SNAPSHOT</version>

  5.            <scope>compile</scope>

  6.        </dependency>

接下来一步比较关键

  • 实现gRPC服务接口

 
   
   
 
  1. public class RPCDateServiceImpl extends RPCDateServiceGrpc.RPCDateServiceImplBase{

  2.    @Override

  3.    public void getDate(RPCDateRequest request, StreamObserver<RPCDateResponse> responseObserver) {

  4.        RPCDateResponse rpcDateResponse = null;

  5.        Date now=new Date();

  6.        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("今天是"+"yyyy年MM月dd日 E kk点mm分”);

  7.        String nowTime = simpleDateFormat.format( now );

  8.        try {

  9.            rpcDateResponse = RPCDateResponse

  10.                    .newBuilder()

  11.                    .setServerDate( "Welcome " + request.getUserName()  + ", " + nowTime )

  12.                    .build();

  13.        } catch (Exception e) {

  14.            responseObserver.onError(e);

  15.        } finally {

  16.            responseObserver.onNext( rpcDateResponse );

  17.        }

  18.        responseObserver.onCompleted();

  19.    }

  20. }

我想此处重写的 getDate()方法并不陌生吧,这正是上文 .proto 文件中定义的Service接口。 此处逻辑比较简单:获取当前时间,并且将其与请求 RPCDateRequest中提取出的 userName字段进行拼接,然后返回给调用端!形成一个闭环

  • 创建gRPC服务端启动类

 
   
   
 
  1. public class GRPCServer {

  2.    private static final int port = 9999;

  3.    public static void main( String[] args ) throws Exception {

  4.        Server server = ServerBuilder.

  5.                forPort(port)

  6.                .addService( new RPCDateServiceImpl() )

  7.                .build().start();

  8.        System.out.println( "grpc服务端启动成功, 端口=" + port );

  9.        server.awaitTermination();

  10.    }

  11. }

端口自定义的9999,也就是在该端口监听。现在可以立即运行GRPCServer,来启动服务端

RPC框架实践之:Google gRPC


开发gRPC客户端

  • 创建基于Maven的项目:Client

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

 
   
   
 
  1.        <dependency>

  2.            <groupId>com.hansonwang99</groupId>

  3.            <artifactId>GrpcAPI</artifactId>

  4.            <version>1.0-SNAPSHOT</version>

  5.            <scope>compile</scope>

  6.        </dependency>

  • 创建gRPC客户端启动类

 
   
   
 
  1. public class GRPCClient {

  2.    private static final String host = localhost”;

  3.    private static final int serverPort = 9999;

  4.    public static void main( String[] args ) throws Exception {

  5.        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress( host, serverPort ).usePlaintext().build();

  6.        try {

  7.            RPCDateServiceGrpc.RPCDateServiceBlockingStub rpcDateService = RPCDateServiceGrpc.newBlockingStub( managedChannel );

  8.            RPCDateRequest  rpcDateRequest = RPCDateRequest

  9.                    .newBuilder()

  10.                    .setUserName(“hansonwang99”)

  11.                    .build();

  12.            RPCDateResponse rpcDateResponse = rpcDateService.getDate( rpcDateRequest );

  13.            System.out.println( rpcDateResponse.getServerDate() );

  14.        } finally {

  15.            managedChannel.shutdown();

  16.        }

  17.    }

  18. }

现在立即启动 GRPCClient!


C-S通信实验

还记得我们的目标吗?

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


后记

本文实验代码在此 → 需要自取:https://gitee.com/hansonwang99/Maven_gRPC

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

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



以上是关于RPC框架实践之:Google gRPC的主要内容,如果未能解决你的问题,请参考以下文章

1Google Grpc 框架源码解析 之 Hello World

grpc实践-学会grpc就是这么简单

Golang gRPC 实践

gRPC 1.11.0 发布,Google 高性能 RPC 框架

Golang RPC 之 gRPC

技术实践:教你用Python搭建gRPC服务