CodeWalk

gRPC通信原理与Protocol Buffers协议

作者:我还是少年 · 2026-05-30 12:55

请详细解释gRPC(Google Remote Procedure Call)的通信原理和Protocol Buffers(protobuf)协议格式。gRPC基于HTTP/2实现了哪些特性(多路复用、双向流)?protobuf相比JSON/XML有什么优势?定义一份简单的service和message并说明代码生成流程。

回答

我还是少年

gRPC核心原理

gRPC基于HTTP/2,使用Protocol Buffers作为接口定义语言(IDL)和序列化协议。

HTTP/2特性利用

  • 多路复用:单个TCP连接上多个gRPC调用并行
  • 二进制帧:头部HPACK压缩,减少传输量
  • 服务端推送:可主动推送数据
  • 流控:HTTP/2内置流控制

四种通信模式:

  1. Unary RPC:客户端发送1个请求,服务端返回1个响应
  2. Server Streaming:客户端1个请求,服务端返回流式响应
  3. Client Streaming:客户端流式发送,服务端返回1个响应
  4. Bidirectional Streaming:双向流式通信

Protocol Buffers

syntax = "proto3";

package com.example;

service UserService {
    rpc GetUser (GetUserRequest) returns (User);
    rpc ListUsers (ListUsersRequest) returns (stream User);
    rpc UpdateUsers (stream UpdateUserRequest) returns (UpdateSummary);
    rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}

message User {
    int32 id = 1;
    string name = 2;
    string email = 3;
    repeated string roles = 4;
}

message GetUserRequest {
    int32 user_id = 1;
}

protobuf vs JSON

特性protobufJSON
序列化大小小(二进制,3-10倍小)大(文本)
序列化速度快(C++/Java原生实现)慢(反射+字符串解析)
可读性差(二进制)好(文本)
版本兼容支持(字段编号)手动处理
是否有Schema强制.proto文件可选(Swagger/OpenAPI)
语言支持12+语言所有语言

代码生成流程

# 1. 定义 .proto 文件
# 2. 编译生成Java代码
protoc --java_out=src/main/java user.proto
protoc --grpc-java_out=src/main/java user.proto

# 3. Maven/Gradle通过protobuf插件自动生成
# Maven: protobuf-maven-plugin
# Gradle: com.google.protobuf

Java服务端实现

class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {
    @Override
    public void getUser(GetUserRequest request, StreamObserver<User> responseObserver) {
        User user = User.newBuilder().setId(request.getUserId()).setName("Alice").build();
        responseObserver.onNext(user);
        responseObserver.onCompleted();
    }
}