目錄
1. gRPC協議介紹及構成
協議分層
協議關鍵字段
2. 示例:Greeter 服務
步驟1:定義 .proto 文件
步驟2:生成代碼
3. Java代碼示例
依賴配置(Maven pom.xml)
服務端實現
客戶端實現
運行流程
關鍵機制
對比 REST API
官網:https://grpc.io/
1. gRPC協議介紹及構成
gRPC(Google Remote Procedure Call)是基于 HTTP/2 和 Protocol Buffers 的高性能RPC框架,核心構成如下:
協議分層
- 傳輸層:基于 HTTP/2,支持多路復用、雙向流、頭部壓縮。
- 數據編碼層:使用 Protocol Buffers(二進制序列化協議),高效壓縮數據。
- 接口定義層:通過
.proto
文件定義服務接口和消息結構。 - 通信模式:
-
- Unary RPC:單次請求-響應。
- Server Streaming:服務端返回流式響應。
- Client Streaming:客戶端發送流式請求。
- Bidirectional Streaming:雙向流式通信。
協議關鍵字段
- HTTP/2 請求頭:
-
:method
:固定為POST
。:path
:標識服務方法,格式為/包名.服務名/方法名
(如/example.Greeter/SayHello
)。content-type
:固定為application/grpc+proto
。
- Trailer 頭:用于傳遞狀態碼(如
grpc-status
)和錯誤信息。
2. 示例:Greeter 服務
步驟1:定義 .proto
文件
syntax = "proto3";
package example;service Greeter {rpc SayHello (HelloRequest) returns (HelloResponse) {}
}message HelloRequest {string name = 1;
}message HelloResponse {string reply = 1;
}
步驟2:生成代碼
使用 protoc
生成Java代碼(需安裝 protoc
和 grpc-java
插件):
protoc --java_out=./src/main/java --grpc-java_out=./src/main/java greeter.proto
生成的文件包括:
HelloRequest.java
/HelloResponse.java
:消息類。GreeterGrpc.java
:包含服務端接口和客戶端存根。
3. Java代碼示例
依賴配置(Maven pom.xml
)
<dependencies><dependency><groupId>io.grpc</groupId><artifactId>grpc-netty</artifactId><version>1.50.0</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-protobuf</artifactId><version>1.50.0</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-stub</artifactId><version>1.50.0</version></dependency>
</dependencies>
<build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.7.0</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.21.7:exe:${os.detected.classifier}</protocArtifact><pluginId>grpc-java</pluginId><pluginArtifact>io.grpc:protoc-gen-grpc-java:1.50.0:exe:${os.detected.classifier}</pluginArtifact></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin></plugins>
</build>
服務端實現
import io.grpc.Server;
import io.grpc.ServerBuilder;
import example.GreeterGrpc;
import example.HelloRequest;
import example.HelloResponse;public class GreeterServer {public static void main(String[] args) throws Exception {// 創建服務端,監聽端口 50051Server server = ServerBuilder.forPort(50051).addService(new GreeterImpl()).build().start();System.out.println("Server started on port 50051");server.awaitTermination();}// 實現服務接口static class GreeterImpl extends GreeterGrpc.GreeterImplBase {@Overridepublic void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {// 處理請求并返回響應String reply = "Hello " + request.getName();HelloResponse response = HelloResponse.newBuilder().setReply(reply).build();responseObserver.onNext(response);responseObserver.onCompleted();}}
}
客戶端實現
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import example.GreeterGrpc;
import example.HelloRequest;
import example.HelloResponse;public class GreeterClient {public static void main(String[] args) {// 創建到服務端的通道ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051).usePlaintext() // 簡化示例,禁用TLS.build();// 創建客戶端存根GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel);// 發送請求并接收響應HelloRequest request = HelloRequest.newBuilder().setName("Alice").build();HelloResponse response = stub.sayHello(request);System.out.println("Server reply: " + response.getReply());// 關閉通道channel.shutdown();}
}
運行流程
- 啟動服務端:運行
GreeterServer
,監聽端口 50051。 - 啟動客戶端:運行
GreeterClient
,發送請求并打印結果。 - 輸出結果:
Server reply: Hello Alice
關鍵機制
- HTTP/2 多路復用:多個請求共享一個TCP連接,降低延遲。
- Protobuf 序列化:二進制格式,體積小、解析快。
- 代碼生成:根據
.proto
自動生成客戶端和服務端代碼,減少手寫邏輯。
對比 REST API
場景 | gRPC 方案 | REST 方案 |
實時聊天 | 雙向流式 | 輪詢或 WebSocket |
批量文件上傳 | 客戶端流式 | 分塊上傳 |
大規模微服務通信 | 高效二進制協議 | JSON over HTTP/1.1 |