优化 RPC 性能需全链路协同:优先用 protobuf 等二进制协议替代 JSON,精简传输字段、复用连接、启用 HTTP/2 压缩与流控,并避免反射式序列化。

在 Go 中优化 RPC 性能,核心是减少序列化成本和网络传输量。这不单是选个快的编码器,而是从协议设计、数据结构、传输层到服务端处理的全链路协同优化。
用二进制协议替代 JSON
JSON 虽易读易调试,但解析慢、体积大、无类型信息。gRPC 默认使用 Protocol Buffers(protobuf),它生成紧凑的二进制格式,且有强类型和代码生成支持,序列化/反序列化速度通常比 JSON 快 3–10 倍。
若不用 gRPC,也可单独集成 protobuf 或更轻量的 FlatBuffers、Cap’n Proto(零拷贝解析)。避免手动实现 JSON-RPC 时默认用 json.Marshal —— 即使改用 easyjson 或 ffjson 加速,仍难追平二进制协议的底子优势。
精简传输数据:只传必需字段
RPC 不是数据库查询,别把整个 struct 全发过去。常见问题包括:
立即学习“go语言免费学习笔记(深入)”;
- 返回结构体嵌套过深(如
User.Profile.Address.City.Name) - 携带大量未使用字段(如后台管理字段透传到前端 API)
- 用通用 map[string]interface{} 代替明确 message 定义
建议:在 proto 文件中按场景拆分 message(如 UserSummary vs UserDetail),客户端按需请求;服务端避免 “select *” 式构造响应,用字段投影或 builder 模式裁剪。
复用连接 + 启用流控与压缩
HTTP/2 是 gRPC 的基础,天然支持多路复用、头部压缩和流控。确保:
- 客户端复用同一个
grpc.ClientConn,不要每次调用都新建连接 - 服务端设置合理的
MaxConcurrentStreams和WriteBufferSize - 对大 payload(如文件元信息、日志片段)启用 gzip 压缩:
grpc.WithCompressor(gzip.NewCompressor())
注意:小消息(4KB 的响应启用。
避免反射式序列化,预生成编解码逻辑
Go 标准库 encoding/gob 或某些自研 RPC 框架依赖反射,运行时开销高。protobuf 通过 protoc-gen-go 生成静态方法,调用路径短、无反射、可内联。
若必须用自定义协议,优先使用 go-codec(支持 msgpack)或 zstd-go 配合预声明 struct,禁用 interface{} 泛型编码。对高频小结构体,甚至可手写扁平化编解码函数(例如将 time.Time 转为 int64 时间戳而非 RFC3339 字符串)。
不复杂但容易忽略:一次 RPC 调用的耗时,往往 60% 以上花在序列化+网络往返上,而不是业务逻辑本身。从 proto 设计开始控制数据粒度,比后期压测调参见效更快。











