場景
ProtoBuf的介紹以及在Java中使用protobuf將對象進行序列化與反序列化:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108667427
Thrift介紹以及Java中使用Thrift實現RPC示例:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108689413
之前講過Protobuf以及Thrift,下面介紹GPRC。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。
實現
gPRC
gRPC 是一個高性能、開源和通用的 RPC 框架,面向移動和 HTTP/2 設計。目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持。
gRPC 一開始由 google 開發,是一款語言中立、平台中立、開源的遠程過程調用(RPC)系統。
gRPC 基於 HTTP/2 標准設計,帶來諸如雙向流、流控、頭部壓縮、單 TCP 連接上的多復用請求等特。這些特性使得其在移動設備上表現更好,更省電和節省空間占用。
在 gRPC 里客戶端應用可以像調用本地對象一樣直接調用另一台不同的機器上服務端應用的方法,使得您能夠更容易地創建分布式應用和服務。與許多 RPC 系統類似,gRPC 也是基於以下理念:定義一個服務,指定其能夠被遠程調用的方法(包含參數和返回類型)。在服務端實現這個接口,並運行一個 gRPC 服務器來處理客戶端調用。在客戶端擁有一個存根能夠像服務端一樣的方法。
gRPC 默認使用 protocol buffers,這是 Google 開源的一套成熟的結構數據序列化機制。
gRPC的Github:
gPRC-JAVA:
https://github.com/grpc/grpc-java
Java中實現GRPC通信
IDEA中新建Maven項目,然后來到gRPC-java的官方的github中將示例中的依賴復制到項目中
<dependencies> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>1.32.1</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.32.1</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.32.1</version> </dependency> </dependencies>
因為gRPC是基於protobuf的,同樣要將.proto文件編譯成代碼。
所以按照其github的指示,引入Maven插件
<build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.6.2</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.32.1:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
至此完整的pom文件代碼
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.badao.grpc</groupId> <artifactId>hellogrpc</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>1.32.1</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.32.1</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.32.1</version> </dependency> </dependencies> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.6.2</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.32.1:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
待導入完成后。
會在右邊Maven面板中的Plugins下多出protobuf插件
然后就是在項目下新建src/main/proto目錄,此插件會去此目錄下找proto文件,在此目錄下新建Person.proto
syntax = "proto3"; package com.badao.proto; option optimize_for =SPEED; option java_package = "com.badao.grpcjava"; option java_outer_classname = "BadaoDataInfo"; option java_multiple_files = true; service PersonService { rpc GetRealNameByUsername(MyRequest) returns (MyResponse) {} } message MyRequest { string username = 1; } message MyResponse { string realname = 2; }
這里的proto文件使用的是proto3的語法,這里的寫法可以將github的代碼克隆下來,然后參考其grpc-java\examples\src\main\proto
目錄下的寫法。
這里描述文件的意思就是定義一個接口PersonService,借口內的方法是GetRealNameByUsername,方法參數是自定義請求參數,方法響應是
自定義響應。
下面的message就是java中的類,分別是自定義的請求實體和響應實體,以及對應的屬性。
然后就是生成代碼。
依次雙擊上面Maven面板插件中的protobuf:complie和protobuf:compile-custom
就會在target下生成對應的實體和相關的請求響應通信相關的類。
gRPC服務端搭建
在src/main/java下新建包com,badao.grpcjava,包下新建PersonServiceImpl類使其繼承 PersonServiceGrpc.PersonServiceImplBase
然后重寫其方法getRealNameByUsername對具體的根據昵稱獲取真實名字的具體實現。
package com.badao.grpcjava; import io.grpc.stub.StreamObserver; public class PersonServiceImpl extends PersonServiceGrpc.PersonServiceImplBase { @Override public void getRealNameByUsername(MyRequest request, StreamObserver<MyResponse> responseObserver) { System.out.println("接收到的客戶端消息為:"+request.getUsername()); responseObserver.onNext(MyResponse.newBuilder().setRealname("公眾號:霸道的程序猿").build()); responseObserver.onCompleted(); } }
然后新建服務端GrpcServer類
package com.badao.grpcjava; import io.grpc.Server; import io.grpc.ServerBuilder; import java.io.IOException; public class GrpcServer { private Server server; private void start() throws IOException { this.server = ServerBuilder.forPort(8899).addService(new PersonServiceImpl()).build().start(); System.out.println("GRPC Java服務端啟動"); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { public void run() { System.out.println("關閉JVM"); GrpcServer.this.stop(); } })); System.out.println("執行到這里"); } private void stop(){ if(null!=this.server){ this.server.shutdown(); } } private void awaitTermination() throws InterruptedException { if(null!=this.server){ this.server.awaitTermination(); } } public static void main(String[] args) throws IOException, InterruptedException { GrpcServer server = new GrpcServer(); server.start(); server.awaitTermination(); } }
這塊的服務端的搭建可以參考gihub上示例代碼的grpc-java\examples\src\main\java\io\grpc\examples\helloworld
目錄下的服務和客戶端的示例代碼
gRPC客戶端的搭建
在上面新建的包下新建GrpcClient客戶端類
package com.badao.grpcjava; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; public class GrpcClient { public static void main(String[] args) { ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost",8899) .usePlaintext().build(); PersonServiceGrpc.PersonServiceBlockingStub blockingStub = PersonServiceGrpc.newBlockingStub(managedChannel); MyResponse myResponse = blockingStub.getRealNameByUsername(MyRequest.newBuilder().setUsername("公眾號:霸道的程序猿").build()); System.out.println(myResponse.getRealname()); } }
然后運行服務端的主方法后
然后再運行客戶端的main方法
此時再查看服務端
示例代碼下載
https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/12874737