gRPC简介

  gRPC是一种RPC框架技术,采用Protocal Buffers(协议缓存) 作为其接口定义的语言(就是Proto来写接口)和基础的消息交换格式。

  在gRPC中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像它是本地对象一样,使您可以更轻松地创建分布式应用程序和服务。与许多RPC系统一样,gRPC基于定义服务的思想,指定可以使用其参数和返回类型远程调用的方法。在服务器端,服务器实现此接口并运行gRPC服务器来处理客户端调用。在客户端,客户端有一个存根(Stub在某些语言中称为客户端),它提供与服务器相同的方法。

  gRPC客户端和服务器可以在各种环境中相互运行和通信 - 从Google内部的服务器到您自己的桌面 - 并且可以使用任何gRPC支持的语言编写。因此,例如,您可以使用Go,Python或Ruby轻松创建Java中的gRPC服务器。此外,最新的Google API将具有gRPC版本的界面,让您可以轻松地在应用程序中构建Google功能。

    使用协议缓存区(Protocal Buffers )

  

  正如您将在我们的示例中更详细地看到的那样,您可以在普通的proto文件中定义gRPC服务,并将RPC方法参数和返回类型指定为协议缓冲区消息:

  

// The greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
} // The request message containing the user's name.
message HelloRequest {
string name = 1;
} // The response message containing the greetings
message HelloReply {
string message = 1;
}

  这里我们将采用protoc特殊的gRPC插件从proto文件生成代码。但是,使用gRPC插件,您可以生成gRPC客户端和服务器代码,十分方便

    搭建项目

  maven配置文件:

  

 <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<grpc.version>1.13.1</grpc.version><!-- CURRENT_GRPC_VERSION -->
<protobuf.version>3.5.1</protobuf.version>
<protoc.version>3.5.1-1</protoc.version>
<netty.tcnative.version>2.0.7.Final</netty.tcnative.version>
</properties>
<dependencies>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-alts</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-testing</artifactId>
<version>${grpc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>${netty.tcnative.version}</version>
</dependency>
<dependency>
<groupId>com.google.api.grpc</groupId>
<artifactId>proto-google-common-protos</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-protocol-buffers</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
<!-- 使用自己从官网下的protoc -->
<!--<protocExecutable>C:/Users/14687/workspace/google/protoc-3.6.0-win32/bin</protocExecutable>-->
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireUpperBoundDeps/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
    注意:这里的  protoc.version 和   protobuf.version 需要保持一致

    编写.proto文件

  在 java 目录下,新建proto文件,在里面写.proto文件,如下:

  

syntax = "proto3";
option java_package = "com.example.service";
package helloword;
// the greeter service definition
service Greeter {
//send a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {
}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}

  提示:用IDEA可以安装相应插件:Protobuf Support(File-->setting-->Plugins-->Browse repositories)

    编写server端

 public class HelloWorldServer {
private static final Logger log = Logger.getLogger(HelloWorldServer.class.getName()); private Server server; public static void main(String[] args) throws IOException, InterruptedException {
final HelloWorldServer server = new HelloWorldServer();
server.start();
server.blockUntilShutdown();
} private void start() throws IOException {
int port = 50051;
//1.forPort 指定监听客户端请求的端口
//2.创建我们的服务端实现类的实例GreeterImpl并将传递给构建器的addService方法
//3.调用build ()并 start()在构建器上为我们的服务创建和启动RPC服务器
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.build()
.start();
log.info("Server stated , listener on port:" + port);
//JVM关闭时调用的钩子
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public synchronized void start() {
System.err.println("*** shutting down gRPC server since JVM is shutting down");
HelloWorldServer.this.stop();
System.err.println("*** server shut down");
}
});
} private void stop() {
if (null != server) {
server.shutdown();
}
} /**
* Await termination on the main thread since the grpc library uses daemon threads.
*
* @throws InterruptedException
*/
private void blockUntilShutdown() throws InterruptedException {
if (null != server) {
server.awaitTermination();
}
} private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
/**
* @param request 请求
* @param responseObserver 响应观察器
*/
@Override
public void sayHello(HelloRequest request,
StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello" + request.getName())
.build();
//返回 reply数据
responseObserver.onNext(reply);
//指定完成gRPC的处理
responseObserver.onCompleted();
}
}
}

    编写client端

public class HelloWordClient {
private static final Logger log = Logger.getLogger(HelloWordClient.class.getName());
private final ManagedChannel channel;
//阻塞/同步 的stub(存根)
private final GreeterGrpc.GreeterBlockingStub blockingStub;
//非阻塞/异步 的stub
private final GreeterGrpc.GreeterStub async; /**
* Greet server. If provided, the first element of {@code args} is the name to use in the
* greeting.
*/
public static void main(String[] args) {
HelloWordClient client = new HelloWordClient("localhost", 50051);
String user = "world";
try {
client.greet(user);
client.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
} public HelloWordClient(String host, int port) {
this(ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build());
} public HelloWordClient(ManagedChannel channel) {
this.channel = channel; blockingStub = GreeterGrpc.newBlockingStub(channel);
async = GreeterGrpc.newStub(channel);
} public void greet(String name) {
log.info("Will try to greet" + name + "..");
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloReply response = null;
try {
//使用阻塞 stub调用
response = blockingStub.sayHello(request);
} catch (StatusRuntimeException e) {
log.info(String.format("rpc failed:%s", e.getStatus()));
}
log.info("Greeting: " + response.getMessage());
} public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
}

gRPC官网

GitHub仓库地址

使用gRPC搭建Server端与Client端的更多相关文章

  1. 在socket的server端处理client端发来的数据

    一.楔子 最近做了一个需求遇到一个坑,归结成一个小问题,其实就是在socket的server端处理client端发来的数据的问题,现将这个问题总结一下,本文将数据在server端以字典的形式存储. 另 ...

  2. 用同一台PC的两个网口实现Iperf的server端和client端

    用同一台PC的两个网口实现Iperf的server端和client端 2015年10月20日 20:35:11 阅读数:2943 有时候需要发包,仅仅需要一定速率的流量,并不需要关心收到报文的大小,一 ...

  3. 【Tech】CAS多机部署Server和Java Client端

    昨天尝试把cas的java client端部署到另外一台机器,结果就有问题了.(localhost部署cas server和java client端参见:http://www.cnblogs.com/ ...

  4. 微服务学习三:springboot与springcloud集成之Eurake的使用(server端,client端)

    这个多亏了网站上的一个大神的博客: http://blog.csdn.net/forezp/article/details/70148833 强烈推荐学习: 1.springcloud是什么,这个大家 ...

  5. Spring Cloud config之三:config-server因为server端和client端的健康检查导致服务超时阻塞问题

    springcloud线上一个问题,当config-server连不上git时,微服务集群慢慢的都挂掉. 在入口层增加了日志跟踪问题: org.springframework.cloud.config ...

  6. 搭建分布式事务组件 seata 的Server 端和Client 端详解(小白都能看懂)

    一,server 端的存储模式为:Server 端 存 储 模 式 (store-mode) 支 持 三 种 : file: ( 默 认 ) 单 机 模 式 , 全 局 事 务 会 话 信 息 内 存 ...

  7. grpc(3):使用 golang 开发 grpc 服务端和client

    1,关于grpc-go golang 能够能够做grpc的服务端和client. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://g ...

  8. 从零开始学习Node.js例子四 多页面实现数学运算 续二(client端和server端)

    1.server端 支持数学运算的服务器,服务器的返回结果用json对象表示. math-server.js //通过监听3000端口使其作为Math Wizard的后台程序 var math = r ...

  9. 【翻译自mos文章】在RHEL7/OL7上安装Oracle 12.1.0.2的server端或者client时,报须要&quot;compat-libstdc++&quot;包

    在RHEL7/OL7上安装Oracle 12.1.0.2的server端或者client时,报须要"compat-libstdc++"包 来源于: Installation of ...

随机推荐

  1. toitorsegit and toitorstsvn文件夹icon冲突不显示

    Go to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer Add a new string value & ...

  2. Dominant Resource Fairness: Fair Allocation of Multiple Resource Types

    Dominant Resource Fairness: Fair Allocation of Multiple Resource Types

  3. T_CODE I18N

    关于T-CODE I18N 最近由于看到很多人遇到SMARTFORMS不能拖拽字段的问题,这个的解决方案 I18N:解决SMARTFORMS的不能从Field name 那边直接把变量拖入右边编辑框 ...

  4. (转)js中__proto__和prototype的区别和关系

    作者:doris链接:https://www.zhihu.com/question/34183746/answer/58155878来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  5. Qt & MySQL

    Qt中如何进行MySQL连接与操作步骤: 1.向工程中的.pro文件增加QT += sql; 2.写一个通用的数据库连接类(Connect),一个static方法(CreateConnection), ...

  6. CountDownLatch,CyclicBarrier,Semaphore的使用

    什么时候使用CountDownLatch CountDownLatch原理和示例 Semaphore信号量的原理和示例 CyclicBarrier的用法 CyclicBarrier 和 CountDo ...

  7. LightOJ - 1038 Race to 1 Again —— 期望

    题目链接:https://vjudge.net/problem/LightOJ-1038 1038 - Race to 1 Again    PDF (English) Statistics Foru ...

  8. 数据库,序列化数据为json字符串

    create PROCEDURE [dbo].[usp_SerializeJSON] @ParameterSQL as varchar(max) AS BEGIN declare @SQL nvarc ...

  9. Linux bash shell环境变量以及语法规范

    摘自: http://blog.csdn.net/abc_ii/article/details/8762739

  10. linux应用之jdk环境的安装(centos)

    一.yum安装 1.执行:yum search jdk 已加载插件:fastestmirror, securityLoading mirror speeds from cached hostfile ...