使用grpc可以用来进行不同系统之间的信息交互,而且grpc不限于java,使用同一个proto文件可以在不同的编程语言之间交互。
上面这张图介绍了proto文件的语法,对应proto3.0,具体更多的内容请参考文档:
http://www.grpc.io/docs/#generating-grpc-code
下面我们先讲一下如何在java中通过proto文件生成java代码,然后再讲如何使用。
添加如下依赖与插件:
- <dependency>
- <groupId>io.grpc</groupId>
- <artifactId>grpc-all</artifactId>
- <version>0.14.0</version>
- </dependency>
- <dependency>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- <version>3.0.0-beta-2</version>
- </dependency>
- <build>
- <extensions>
- <extension>
- <groupId>kr.motd.maven</groupId>
- <artifactId>os-maven-plugin</artifactId>
- <version>1.4.1.Final</version>
- </extension>
- </extensions>
- <plugins>
- <!-- protobuf -->
- <plugin>
- <groupId>org.xolstice.maven.plugins</groupId>
- <artifactId>protobuf-maven-plugin</artifactId>
- <version>0.5.0</version>
- <configuration>
- <protocArtifact>com.google.protobuf:protoc:3.0.0-beta-2:exe:${os.detected.classifier}</protocArtifact>
- <pluginId>grpc-java</pluginId>
- <pluginArtifact>io.grpc:protoc-gen-grpc-java:0.14.0:exe:${os.detected.classifier}</pluginArtifact>
- <protoSourceRoot>src/main/resources/proto</protoSourceRoot>
- </configuration>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- <goal>compile-custom</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
这样一来,在进行mvn compile时,会自动去src/main/resources/proto目录下查找proto文件,并在target目录里生成对应的.java、.class文件。
下面我们写一个服务端、一个客户端的helloworld程序,proto文件如下:
- syntax = "proto3";
- package grpc;
- option java_package = "com.zk_chs.grpc";
- option java_outer_classname = "HelloWorldServiceProto";
- option java_multiple_files = true;
- service HelloWorldService {
- rpc SayHello (HelloWorldRequest) returns (HelloWorldResponse) {}
- }
- message HelloWorldRequest {
- string request = 1;
- }
- message HelloWorldResponse {
- string response = 1;
- }
当有option java_package存在时,会覆盖package属性,生成的文件如下:
接下来,需要先实现我们定义的HelloWorldService服务接口,该接口只需在服务端实现,客户端不用实现:
- public class HelloWorldRpcServiceImpl implements HelloWorldRpcServiceGrpc.HelloWorldRpcService {
- @Override
- public void sayHello(HelloWorldRequest request, StreamObserver<HelloWorldResponse> responseObserver) {
- String req = request.getRequest();
- HelloWorldResponse resp = HelloWorldResponse.newBuilder()
- .setResponse("hello " + req)
- .build();
- responseObserver.onNext(resp);
- responseObserver.onCompleted();
- }
- }
服务端实现:
- public class GrpcServer {
- private final int port = 38628;
- private Server server;
- private void start() throws IOException {
- server = ServerBuilder.forPort(port)
- .addService(HelloWorldRpcServiceGrpc.bindService(new HelloWorldRpcServiceImpl())) // 能继续使用.addService添加多个服务
- .build()
- .start();
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- GrpcServer.this.stop();
- }
- });
- }
- private void stop() {
- if (server != null) {
- server.shutdown();
- }
- }
- private void blockUntilShutdown() throws InterruptedException {
- if (server != null) {
- server.awaitTermination();
- }
- }
- public static void main(String[] args) throws IOException, InterruptedException {
- final GrpcServer server = new GrpcServer();
- server.start();
- server.blockUntilShutdown();
- }
- }
客户端实现:
- public class GrpcClient {
- private final ManagedChannel channel;
- private final HelloWorldRpcServiceGrpc.HelloWorldRpcServiceBlockingStub blockingStub;
- public GrpcClient(String host, int port) {
- channel = ManagedChannelBuilder.forAddress(host, port)
- .usePlaintext(true)
- .build();
- blockingStub = HelloWorldRpcServiceGrpc.newBlockingStub(channel);
- }
- public void shutdown() throws InterruptedException {
- channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
- }
- public String request(String req) {
- HelloWorldRequest request = HelloWorldRequest.newBuilder()
- .setRequest(req)
- .build();
- return blockingStub.sayHello(request).getResponse();
- }
- public static void main(String[] args) throws Exception {
- GrpcClient client = new GrpcClient("localhost", 38628);
- String req = "world!";
- String response = client.request(req);
- System.out.println(response);
- }
- }
然后进行测试,首先启动GrpcServer,再运行GrpcClient,在client的控制台能看到如下信息:
一个简易的grpc服务就完成了,当然,还有很多的不足:
1、例如异常信息处理(grpc有内置的异常信息)
2、连接每次都会断开,没有重复利用,效率低
下次的博客大概会介绍一下解决方法,比如采用commons-pool2连接池
Grpc应用,基本实现,http://zk-chs.iteye.com/blog/2308422
Grpc应用,搭配commons-pool2连接池实现连接复用,http://zk-chs.iteye.com/blog/2308730
相关推荐
我们将使用Worker Services和Asp.Net 5 Grpc应用程序来构建定义原型服务定义合同的客户端和服务器gRPC组件。 基本上,我们将仅使用gRPC通信来实现电子商务逻辑。 我们将有3个gRPC服务器应用程序,它们是产品-...
该项目中的Django应用程序是基本框架,没有序列化程序,URL和构建文件。 它包含views及其实现,我们将在grpc_services使用grpc_services 。 设置virtualenv pip install virtualenv virtualenv .venv 安装要求 $ ...
使用了最新的grpc依赖包,应用演示了和服务器基本的grpc通讯,大部分接口是同步的,也有异步的,采用了Stream模式 ,就是把本地录音数据推流到服务器,我这边只是APP端代码,服务器代码可以根据app端实现,大致能...
高效性能:OpenCV代码经过高度优化,能够利用多核CPU、GPU以及特定硬件加速(如Intel IPP、OpenCL等),实现高速图像处理和实时计算机视觉应用。 多语言支持:尽管OpenCV主要使用C++编写,但它提供了丰富的API...
> + RPC在微服务、分布式系统、Web服务器方面应用太广泛了,需要对底层通信过程有基本认识 > + Nignx、Hadoop、K8s、Tensorflow等系统或软件的底层源码大多是关于RPC的 > + 可以更加熟悉地使用已有的RPC框架,甚至...
请不要以PR形式提交作品,因为这些作品是公开可见的任务在此grpc的api/文件夹中,有一个用于投票服务的基本grpc服务定义。 此服务包含用于创建,列出并投票的RPC voteable项目。 cmd/还有一个“ hello world” go...
它为分布式多人游戏和服务器端应用程序提供了基本的开发框架。 入门 先决条件 > = 1.10 (用于服务发现) (可选,用于发送和接收rpc,如果愿意,也可以使用grpc实现) (可选:用于在容器运行ETCD和NAT依赖性)...
使用可重用的 UI 组件进行开发,这些组件可以利用 WebAssembly 实现接近本机的性能。 使用 ASP.NET Core Web API 开发 RESTful HTTP 服务。 开发以页面为中心的 Web 应用程序,并清晰地分离关注点。 使用模型-视图-...
基本实现 将从每个产品中获取所有信息并存储 Squzy Web GUI-帮助与squzy进行交互。 适用于Works GUI +应用程序的Squzy API服务器 Squzy Application Monitoring服务器-从应用程序收集指标 Squzy事件管理器-分析指标...
它具有一个gRPC API,该API支持启动/取消/监视示例处理任务,并包括一个用于运行服务器和客户端实现的命令行应用程序(称为archer )。如果用户希望CLIMB对数据运行,则需要在CLIMB处理数据之前在本地检查数据并将其...
有两种微服务,一种是公开REST API的Web服务,另一种是实现与用户一起工作的功能的RPC微服务,基本上,该服务负责业务逻辑。 用户将HTTP请求发送到Web服务后,它将处理传入的请求,准备数据并使用protobuf模型通过...
Java服务/客户端:您可以使用通过原始协议实现/访问rpcx服务。 如果您可以编写Go方法,则还可以编写rpc服务。 用rpcx编写rpc应用程序非常容易。 安装 安装基本功能: go get -v github.com/smallnest/rpcx/... ...