一、gRPC概念介紹
gRPC(Google Remote Procedure Call,Google遠程過程調用)是一個現代開源高性能遠程過程調用(RPC)框架,可以在任何環境中運行。它由Google開發,旨在幫助開發人員更輕松地構建分布式應用,特別是當代碼可能在不同地方運行的時候。
gRPC是一個高性能、開源和通用的RPC框架,它基于HTTP/2設計,并支持多種編程語言和平臺。
隨著其開源和廣泛應用,gRPC已成為云原生計算基金會(CNCF)的一個孵化項目,被大量組織和企業采用。
核心特點
- 高性能:gRPC使用HTTP/2作為傳輸協議,支持二進制組幀、多路復用、雙向全雙工通信和流式處理等功能,從而顯著提高性能。與JSON相比,gRPC的消息序列化速度更快,消息體積更小。
- 跨平臺與跨語言:gRPC支持多種編程語言和平臺,如C++、Java、Python、Go等,使得開發人員可以在不同的環境中使用統一的RPC框架。
- 靈活性與可擴展性:gRPC提供了豐富的功能,如負載平衡、跟蹤、健康檢查和身份驗證等,這些功能都是可插拔的,可以根據需要進行配置和擴展。
- 安全性:gRPC支持TLS加密,確保數據在傳輸過程中的安全性。同時,它還支持多種認證機制,如JWT(JSON Web Tokens)等,以確保服務的訪問安全。
工作原理
- 服務定義:在gRPC中,服務通過.proto文件進行定義。這些文件包含了服務的接口描述、消息類型等信息。開發人員可以使用Protocol Buffers(簡稱Protobuf)來定義這些結構化的消息。
- 代碼生成:基于.proto文件,gRPC提供了protoc編譯器來生成支持多種編程語言的客戶端和服務端代碼。這使得開發人員可以輕松地實現跨語言的RPC調用。
- 通信過程:在客戶端和服務端之間,gRPC通過HTTP/2協議進行通信。客戶端發送請求到服務端,服務端處理請求并返回響應。整個通信過程都是基于二進制格式的,從而提高了性能和效率。
應用場景
- 微服務架構:在微服務架構中,gRPC可以有效地連接多語言服務,實現服務間的快速通信。
- 分布式計算:gRPC適用于分布式計算的最后一英里,將設備、移動應用程序和瀏覽器連接到后端服務。
- API設計:與REST API相比,gRPC提供了一種更加高效和靈活的API設計風格,適用于需要高性能和低延遲的應用場景。
二、簡單使用步驟
首先,你需要定義gRPC服務。這里我們使用一個簡單的helloworld.proto
文件。
1. helloworld.proto
syntax = "proto3";option java_multiple_files = true;
option java_package = "com.example.grpc";
option java_outer_classname = "HelloWorldProto";package helloworld;service HelloWorldService {rpc SayHello (HelloRequest) returns (HelloReply) {}
}message HelloRequest {string name = 1;
}message HelloReply {string message = 1;
}
2. 生成Java代碼
使用protoc編譯器和gRPC插件生成Java代碼。
protoc --java_out=./src/main/java --grpc-java_out=./src/main/java --plugin=protoc-gen-grpc-java=/path/to/protoc-gen-grpc-java-1.x.x-linux-x86_64.exe helloworld.proto
確保將/path/to/protoc-gen-grpc-java-1.x.x-linux-x86_64.exe
替換為你的protoc-gen-grpc-java
插件的實際路徑。
3. 服務端實現
在Spring Boot應用中,你可以創建一個組件來實現gRPC服務。
package com.example.grpc;import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;@GrpcService
public class HelloWorldServiceImpl extends HelloWorldServiceGrpc.HelloWorldServiceImplBase {@Overridepublic void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {String message = "Hello, " + req.getName() + "!";HelloReply reply = HelloReply.newBuilder().setMessage(message).build();responseObserver.onNext(reply);responseObserver.onCompleted();}
}
4. 客戶端調用
在Spring Boot應用中,你可以創建一個服務來調用gRPC服務。這里使用JUnit單元測試
import com.example.grpc.HelloReply;
import com.example.grpc.HelloRequest;
import com.example.grpc.HelloWorldServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.junit.jupiter.api.Test;public class HelloWorldClientServiceTest {@Testpublic void sayHello() {ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:9091").usePlaintext().build();HelloWorldServiceGrpc.HelloWorldServiceBlockingStub stub = HelloWorldServiceGrpc.newBlockingStub(channel);HelloReply response = stub.sayHello(HelloRequest.newBuilder().setName("Lisa").build());System.out.println("response = " + response);channel.shutdown();}
}
5. 構建和運行
確保你的pom.xml
中包含了必要的gRPC和Spring Boot依賴。
然后執行maven compile
指令生成java代碼
mvn compile
啟動SpringBoot服務端,然后運行測試用例,得到如下結果:
response = message: "Hello, Lisa!"
三、添加gRPC相關依賴包
參考 grpc-spring
在Spring Boot項目中使用gRPC,你需要在項目的pom.xml
中添加相關的gRPC依賴。
以下是在Maven項目中添加gRPC依賴的示例。
<dependencies><dependency><groupId>com.salesforce.servicelibs</groupId><artifactId>jprotoc</artifactId><version>1.2.2</version></dependency><dependency><groupId>net.devh</groupId><artifactId>grpc-spring-boot-starter</artifactId><version>${grpc-spring-boot-starter.version}</version></dependency>
</dependencies><properties><protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version><protoc.version>3.25.1</protoc.version><grpc-java.version>1.64.0</grpc-java.version><os-maven-plugin.version>1.7.1</os-maven-plugin.version>
</properties>
請注意,你需要將${grpc-java.version}
、${grpc-spring-boot-starter.version}
替換為你想要使用的具體版本號。
這些依賴項包括了gRPC的基礎庫、與Protobuf的集成、以及Spring Boot對gRPC的支持。確保你使用的版本是兼容的,并根據你的項目需求進行調整。如果你還需要使用到其他的gRPC功能(如安全認證、健康檢查等),你可能需要添加更多的依賴項。
四、使用Maven插件自動生成proto對應代碼
參考 os-maven-plugin 和 protobuf-maven-plugin
如果你希望通過maven編譯時自動生成proto對應的java代碼,則需要添加Maven插件和相關依賴
<properties><protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version><protoc.version>3.25.1</protoc.version><grpc-java.version>1.64.0</grpc-java.version><os-maven-plugin.version>1.7.1</os-maven-plugin.version><grpc-spring-boot-starter.version>3.1.0.RELEASE</grpc-spring-boot-starter.version>
</properties>
//...//
<dependencies><dependency><groupId>com.salesforce.servicelibs</groupId><artifactId>jprotoc</artifactId><version>1.2.2</version></dependency><!-- gRPC Server + Client --><dependency><groupId>net.devh</groupId><artifactId>grpc-spring-boot-starter</artifactId><version>${grpc-spring-boot-starter.version}</version></dependency>
</dependencies>
// ... //<build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>${os-maven-plugin.version}</version></extension></extensions><pluginManagement><plugins><!-- protobuf-maven-plugin --><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>${protobuf-maven-plugin.version}</version><extensions>true</extensions><executions><execution><id>protoc-compile</id><phase>generate-sources</phase><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution><execution><id>protoc-test-compile</id><phase>generate-test-sources</phase><goals><goal>test-compile</goal><goal>test-compile-custom</goal></goals></execution></executions><configuration><protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact><attachProtoSources>true</attachProtoSources><useArgumentFile>true</useArgumentFile><writeDescriptorSet>false</writeDescriptorSet><attachDescriptorSet>false</attachDescriptorSet><includeDependenciesInDescriptorSet>false</includeDependenciesInDescriptorSet><checkStaleness>true</checkStaleness><pluginId>grpc-java</pluginId><pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact><protocPlugins></protocPlugins></configuration></plugin></plugins></pluginManagement><plugins><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId></plugin></plugins>
</build>
通過上面配置后,你就可以在項目中通過指令mvn compile
生成proto對應的java代碼,不需要通過外包指令了。
參考
- https://protobuf.com.cn/overview/
- https://protobuf.dev/getting-started/javatutorial/
- https://protobuf.dev/reference/java/java-generated/
- https://protobuf.dev/programming-guides/proto3/
- https://github.com/grpc-ecosystem/grpc-spring
- https://www.xolstice.org/protobuf-maven-plugin/
- https://github.com/trustin/os-maven-plugin/