概述

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 等等

  • 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的namespacepackage 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

代码生成结果如下所示

好了,既然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()过程,并将结果取到客户端来显示!

后记

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

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

  • RPC框架实践之:Apache Thrift

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

  • 微服务调用链追踪中心搭建

  • 利用K8S技术栈打造个人私有云连载文章

  • Docker容器可视化监控中心搭建

  • 利用ELK搭建Docker容器化应用日志中心

  • Spring Boot应用监控实战

作者更多 务实、能看懂、可复现的 原创文章尽在公众号 CodeSheep

©著作权归作者所有:来自51CTO博客作者mb5fdcae83766b7的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. RPC框架实践之:Apache Thrift
  2. JavaWeb-LayUI框架的介绍与使用方式(前端框架篇)
  3. 13个帮你提高开发效率的现代CSS框架[每日前端夜话0x67]
  4. Scrapy框架的使用之Scrapy爬取新浪微博
  5. Scrapy框架的使用之Scrapyrt的使用
  6. Scrapy框架的使用之Scrapy通用爬虫
  7. Scrapy框架的使用之Scrapy框架介绍
  8. Scrapy框架的使用之Item Pipeline的用法
  9. Scrapy框架的使用之Spider Middleware的用法

随机推荐

  1. android 中文 api (43) ―― Chronometer
  2. 在android studio 2.1 实现简单的ndk
  3. Android(安卓)liveData 和ViewModel 使用
  4. android万能驱动制作方法
  5. Android从文件目录中写入和读取图片
  6. Android 电话的反射调用机制实现静默接听
  7. android Intent用法归纳
  8. 我使用过的 控件的一些特性(layout_weight
  9. 2011.09.21——— android 动态壁纸开发
  10. RubyMotion 3发布,支持Android和WatchKit