Java中Grpc实例创建负载均衡的示例分析(grpc,java,编程语言)

时间:2024-05-02 06:40:54 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

Grpc是googe开发的,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。新公司的项目服务之间的调用使用的Grpc来实现服务间的调用,这边一开始接到的工作内容是基于Nginx实现Grpc服务端的负载均衡。Nginx的1.13及以上版本是支持grpc的反向代理和负载均衡的。但是公司的nginx服务器的版本是1.10的,所以没办法直接使用grpc的代理。只能使用更底层的tcp层的负载均衡。最终服务跑起来是感觉挺简单的,但是nginx的基础太差,所以过程有点曲折。还是记录下吧。

文章分两部分,一个是创建简单的Grpc客户端和服务端的例子(其实也是用的网上的demo,这边就贴一下源码,讲下更细的实现步骤),然后对比下Nginx的Grpc负载均衡和Tcp的负载均衡。

一、Java创建Grpc客户端和服务端的例子(创建的配置信息相关的代码基本网上博客的,忘记是哪篇文章了,所以暂时没法给出转载链接。)

  1、在开发工具ide上创建一个maven project。打包方式选择jar。

  2、在POM.xml上增加grpc相关的依赖及maven的打包插件

<dependencies><dependency><groupId>io.grpc</groupId><artifactId>grpc-netty</artifactId><version>1.17.1</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-protobuf</artifactId><version>1.17.1</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-stub</artifactId><version>1.17.1</version></dependency></dependencies><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><protocArtifact>com.google.protobuf:protoc:3.0.0:exe:${os.detected.classifier}</protocArtifact><pluginId>grpc-java</pluginId><pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.0:exe:${os.detected.classifier}</pluginArtifact></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>

  3、在项目下的路径src/main下面创建proto文件夹,并在里面创建一个hello.proto文件。具体如下截图。

  Java中Grpc实例创建负载均衡的示例分析

  4、在hello.proto文件上输入,相应的配置信息,用来映射生成java代码。里面的内容就是生成一个MyRPC的服务提供一个sayHi的接口,接口需要传递一个request类的实例,该request实例只有一个name的字段。然后进行相应的业务代码处理之后,返回一个response类的实例,也是只有一个name的字段。

    如果进行到这边,看到第2步添加依赖上面的<execution>标签可能报错,先暂时不要管他。直接进行第5步。

syntax="proto3";optionjava_package="com.qidai.proto";optionjava_outer_classname="MyThing";messageRequest{stringname=1;}messageResponse{stringname=2;}serviceMyRPC{rpcsayHi(Request)returns(Response);}

  5、运行项目,右击项目Run as -->maven build....->protobuf:compile以及protobuf:compile-custom,这样就编译生成了相应的代码了。不过存放的路径不对,需要自己拷贝到相应的项目目录下。

Java中Grpc实例创建负载均衡的示例分析

  6、grpc的客户端和服务端代码需要自己编写。不过这一块的demo已经很全了。c+v然后改成自己的自己需要的就行了。

  服务端demo:

packageserver;importcom.qidai.proto.MyRPCGrpc;importcom.qidai.proto.MyThing;importio.grpc.ServerBuilder;importio.grpc.stub.StreamObserver;importservice.RequestImpl;importjava.io.IOException;publicclassServer{privatestaticfinalintPORT=2222;privatefinalio.grpc.Serverserver;publicServer()throwsIOException{//这个部分启动serverthis.server=ServerBuilder.forPort(PORT).addService(newRequestImpl()).build().start();System.out.println("Server1Started...");}privatevoidstop(){if(server!=null){server.shutdown();}}privatevoidblockUntilShutdown()throwsInterruptedException{if(server!=null){server.awaitTermination();}}publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{Serverserver=newServer();//blockServer防止关闭server.blockUntilShutdown();}}

  客户端demo

packageclient;importcom.qidai.proto.MyRPCGrpc;importcom.qidai.proto.MyRPCGrpc.MyRPCBlockingStub;importcom.qidai.proto.MyThing;importio.grpc.ManagedChannel;importio.grpc.ManagedChannelBuilder;importjava.util.concurrent.TimeUnit;publicclassClient{privatefinalManagedChannelBuilder<?>managedChannelBuilder;privatefinalMyRPCBlockingStubblockingStub;privatefinalManagedChannelchannel;publicClient(Stringname,intport){managedChannelBuilder=ManagedChannelBuilder.forAddress(name,port);channel=managedChannelBuilder.usePlaintext().build();blockingStub=MyRPCGrpc.newBlockingStub(channel);}publicvoidshutdown()throwsInterruptedException{channel.shutdown().awaitTermination(5,TimeUnit.SECONDS);}publicvoidsayHi(Stringname){MyThing.Requestrequest=MyThing.Request.newBuilder().setName(name).build();MyThing.Responseresponse=blockingStub.sayHi(request);System.out.println(response.getName());}publicstaticvoidmain(String[]args)throwsException{Clientclient=newClient("localhost",5005);for(inti=0;i<10;i++){Thread.sleep(1000);//进行rpc调用的真正逻辑client.sayHi("HelloServer1111->5005"+i);}client.shutdown();Clientclient2=newClient("localhost",5005);for(inti=0;i<10;i++){Thread.sleep(1000);//进行rpc调用的真正逻辑client2.sayHi("HelloServer2222->5005"+i);}client2.shutdown();}}

  7、接下来就是才是比较关键的一步,实现自己的grpc服务端的业务代码。主要的关键步骤就是继承grpc自动映射出来的抽象类。是不是很熟悉,没错就是proto文件里面配置的服务。然后重写服务里面配置的方法即可。最后放心大胆的去根据传递的request参数去做相关的业务逻辑的处理。并用response封装需要返回的接口。(此处的request与response均是grcp根据proto配置文件映射出来的相关实体类。)

packageservice;importcom.qidai.proto.MyRPCGrpc.MyRPCImplBase;importcom.qidai.proto.MyThing.Response;publicclassRequestImplextendsMyRPCImplBase{@OverridepublicvoidsayHi(com.qidai.proto.MyThing.Requestrequest,io.grpc.stub.StreamObserver<com.qidai.proto.MyThing.Response>responseObserver){//proto文件上定义的response返回信息Responseresponse;System.out.println("Request>>>say::"+request.getName());//AccountQryResponseresponse=QryAccountProto.AccountQryResponse.newBuilder().setRc(1).setAmount(666).build();response=Response.newBuilder().setName("Response11111>>>say:::hello_client"+request.getName()).build();responseObserver.onNext(response);responseObserver.onCompleted();}}

  二、Grpc服务基于nginx(1.12.2)实现负载均衡。下面直接贴nginx相关的配置,服务端和客户端的代码改动都很小。只需调整ip和port的值即可。其他的不需要改动。

  TCP层负载均衡配置

stream{log_formatproxy'$remote_addr[$time_local]''$protocol$status$bytes_sent$bytes_received''$session_time"$upstream_addr"''"$upstream_bytes_sent""$upstream_bytes_received""$upstream_connect_time"';include./conf.d/*.tcpstream;upstreamgrpc{server127.0.0.1:2223;server127.0.0.1:2222;}server{error_loglogs/device5001_error.log;access_loglogs/device5001_access.logproxy;listen5005;proxy_passgrpc;}}

  grpc的负载均衡配置(grpc的支持在nginx1.13之后才有,所以这里是1.17.0)

http{includemime.types;default_typeapplication/octet-stream;log_formatmain'$remote_addr-$remote_user[$time_local]"$request"''$status$body_bytes_sent"$http_referer"''"$http_user_agent""$http_x_forwarded_for"';access_loglogs/access.logmain;sendfileon;keepalive_timeout65;gzipon;upstreamgrpcservers{server127.0.0.1:2222;server127.0.0.1:2223;}server{listen8080http2;server_namelocalhost;location/{grpc_passgrpc://grpcservers;}}}

  最后分别启动nginx1.12.2和nginx1.17.0,并在ide上启动服务端和客户端,更改相应的客户端端口。就可以看到控制台打印不同的信息了。tcp和grcp的负载均衡的效果是不一样的。这也是我客户端new 了一个client,然后又new 了一个client2的原因。比较懒,效果图就不贴了。

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Java中Grpc实例创建负载均衡的示例分析的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:C#怎么把EXCEL数据转换成DataTable下一篇:

33 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18