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. CUDA: 共享内存与同步

    CUDA C支持共享内存, 将CUDA C关键字__shared__添加到变量声明中,将使这个变量驻留在共享内存中.对在GPU上启动的每个线程块,CUDA C编译器都将创建该变量的一个副本.线程块中的 ...

  2. linux下安装https证书

    https://www.aliyun.com/jiaocheng/165422.html

  3. 《CSS权威指南(第三版)》---第二章 选择器

    本章的主要内容是,怎么获取文档中的元素给予渲染: 1.元素选择器: 2.ID选择器: 3.CLSSS选择器: 4.通配选择器:*; 5.属性选择器:selector[] 6.部分属性选择器: sele ...

  4. 吴恩达机器学习笔记(二) —— Logistic回归

    主要内容: 一.回归与分类 二.Logistic模型即sigmoid function 三.decision boundary 决策边界 四.cost function 代价函数 五.梯度下降 六.自 ...

  5. 51Nod 1294 修改数组 —— LIS

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1294 1294 修改数组  题目来源: HackerRank ...

  6. winform中通过事件实现窗体传值思路【待修改】

    Form2向Form1传值         private Form1 form1;//定义一个类型为Form1类型的字段,用于存储传递过来的Form对象         public void Se ...

  7. 使用.net实现ZooKeeper客户端

    最近在项目中用到ZooKeeper, 通过Java连接比较容易,.net项目就没那么容易,尤其对于不熟悉Linux的开发人员,这里写点搭建ZooKeeper测试环境的经验,供参考. 背景知识: Zoo ...

  8. 线程池ThreadPool的常用方法介绍

    线程池ThreadPool的常用方法介绍 如果您理解了线程池目的及优点后,让我们温故下线程池的常用的几个方法: 1. public static Boolean QueueUserWorkItem(W ...

  9. EmbarassedBirds全体开发人员落泪

    Github (李昆乘,赖展飞) 现阶段还在开发后期,API调试过程中. 本周无法上线. 全体开发人员留下眼泪. 贴上几个功能图, 给大家尝尝鲜吧! 现阶段仍在API调试 因为队员李昆乘经常出去玩没有 ...

  10. hdu1085Holding Bin-Laden Captive!组合问题

    题目连接 题目意思:有单位价值为1 2 5的三种硬币,分别给出他们的数量,求用这些硬币不能组成的最小的价值 解题思路:普通的母函数 普通的母函数: 利用母函数的思想可以解决很多组合问题,下面举例说明: ...