文档
gRPC 微服务通信入门教程
第一章:gRPC vs REST
| 维度 | gRPC | REST |
|---|---|---|
| 协议 | HTTP/2 | HTTP/1.1 |
| 序列化 | Protobuf(二进制) | JSON(文本) |
| 接口定义 | .proto | OpenAPI/Swagger |
| 代码生成 | 自动(多语言) | 手动或工具 |
| 流式 | 原生支持 | 需 WebSocket |
| 浏览器 | 需要 gRPC-Web | 原生支持 |
| 性能 | 高 3-10 倍 | 基准 |
| 调试 | 需工具 | 浏览器可见 |
结论:微服务内部通信用 gRPC;对外 API 用 REST(或 grpc-gateway 自动转换)。
第二章:Protobuf 语言指南
syntax = "proto3";
// 消息定义
message User {
int64 id = 1; // 字段编号(不是值)
string name = 2;
string email = 3;
repeated string tags = 4; // 数组
}
// 服务定义
service UserService {
rpc GetUser(UserRequest) returns (User);
rpc ListUsers(UserFilter) returns (stream User);
}
字段编号一旦分配不要修改(前向后向兼容的关键)。
第三章:四种通信模式详解
Unary(一元调用)
最常用。请求→响应,类似 HTTP 调用。
Server Streaming(服务端流)
适合:大量数据推送。如日志订阅、行情推送。
Client Streaming(客户端流)
适合:文件上传、数据批量处理。
Bidirectional Streaming(双向流)
适合:聊天、实时协作编辑、游戏。
第四章:拦截器
gRPC 拦截器类似 HTTP 中间件:
// 服务端一元拦截器
func loggingInterceptor(ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
start := time.Now()
resp, err := handler(ctx, req)
log.Printf("%s took %v", info.FullMethod, time.Since(start))
return resp, err
}
第五章:最佳实践
- Deadline:每次调用都设 Deadline,避免雪崩
- 重试:使用 gRPC Retry Policy(非幂等操作慎用)
- 断路器:配合 Istio/Envoy 实现 Circuit Breaking
- 元数据:用 gRPC Metadata 传递 traceId/userId(而非请求体)
- TLS:生产环境必须启用 mTLS
思考题
- Protobuf 为什么比 JSON 快?字段编号在其中起什么作用?
- gRPC 的 HTTP/2 多路复用解决了什么问题?为什么 HTTP/1.1 的连接复用(Keep-Alive)不够?
- grpc-gateway 如何做到一份 proto 同时提供 gRPC 和 REST 两种接口?