第二章:gRPC通信模型与协议

聊透明加密改造之前,得先把gRPC的底子摸透。说白了,加密改的是数据在“路上”的形态。你不清楚数据怎么打包、怎么发、怎么流,那加密点都找不对。

这一章,我带你拆开gRPC的通信模型。从数据编码到传输协议,再到三种通信模式。都是实战里绕不开的硬知识。

2.1 Protobuf 编码原理

gRPC默认用Protobuf做序列化。这不是偶然。我的项目经验告诉我,选对序列化方式,性能差一个数量级。

2.1.1 为什么是Protobuf?

你想想看,相比JSON,Protobuf有什么好处?

  • 体积小——二进制编码,没有冗余的字段名
  • 速度快——解析时几乎零拷贝,直接读偏移量
  • 强类型——.proto文件就是契约,服务端和客户端必须对齐
核心观点: Protobuf的紧凑性是实现“透明加密”的基础。加密后的数据如果膨胀过大,性能会崩。Protobuf压缩完,加密的开销才可控。

2.1.2 编码细节:Varint 与 Tag-Len-Val

Protobuf的编码原理,说白了就两句话:小整数用Varint压缩,大字段用TLV打包。

拿一段proto定义举例:

message UserRequest {
  int32  user_id = 1;
  string name    = 2;
}

假设user_id = 150,name = "alice”。序列化后长什么样?

字段 Key (Tag) Value
user_id 0x08 0x96 0x01
name 0x12 0x05 0x61 0x6c 0x69 0x63 0x65
避坑指南: 我曾经在旧版本里把字段编号从2改成了3,结果客户端和服务端没同时更新。解析出来的数据全错位了。记住,字段编号一旦上线,就别改。

2.2 HTTP/2 多路复用

gRPC跑在HTTP/2上。这不是偶然。HTTP/2的多路复用,是gRPC高性能的核心秘诀。

2.2.1 为什么不是HTTP/1.1?

HTTP/1.1有队头阻塞的问题。一个请求卡住了,后面的都得排队。我刚开始做微服务时,就因为这个问题吃了大亏。

HTTP/2怎么解决的?它引入了一个概念——流。

  • 一个TCP连接上可以有多个流
  • 流之间完全并行,互不阻塞
  • 每个流有唯一的流ID

2.2.2 帧、流、多路复用的关系

HTTP/2的数据被切分成帧。帧是传输的最小单位。多个帧组成一个流。

你想想看,一个TCP连接里同时跑多个请求。每个请求的数据被切成帧,帧与帧混杂着传输。接收端通过流ID把数据重新拼回去。

关键启发: 透明加密改造时,我们必须在“帧”这一层做处理。不能等到整个流都收完了再解密,那样延迟会爆炸。

2.3 流式通信模式详解

gRPC支持四种通信模式。我个人强烈建议,在写加密中间件之前,先把这四种模式搞明白。因为不同模式的加密点和解密时机完全不同。

2.3.1 四种模式对比

模式 描述 典型场景
Unary (一元) 客户端发一个请求,服务器回一个响应 查询用户信息
Server Streaming 客户端发一个请求,服务器持续回数据 实时新闻推送
Client Streaming 客户端持续发送,服务器最后回一个 批量上传日志
Bidirectional Streaming 双方独立发送,可同时读写 实时语音对话

2.3.2 Unary 模式

这是最简单的模式。我说句实话,80%的业务场景用Unary就够了。

请求和响应各一条消息。加密改造也很直接:在客户端发送前加密消息体,在服务端收到后解密。

2.3.3 Server Streaming 模式

这种模式下,客户端只发一次请求。服务器持续返回多条消息。

加密的难点在哪?服务端每发一条都要加密,不能等所有消息都攒在一起再处理。

注意: Server Streaming的加密中间件,必须在每次Send方法中做加密操作。我见过有人在Send之前统一加密,结果流已经关闭了。

2.3.4 Client Streaming 与 Bidirectional

Client Streaming里,客户端持续发送。加密必须在Send之前做。服务端收到后立即解密。

Bidirectional更复杂。双方互不等待,都在独立读写。加密必须同时处理Send和Recv。

实战建议: 我刚开始改造Bidirectional流时,遇到过一个死锁问题。双方都在等对方先发数据。后来我在Send和Recv之间加了超时控制,问题才解决。
gRPC通信模型与协议核心结构 第2章:gRPC通信模型与协议 Protobuf编码 HTTP/2多路复用 流式通信模式 Varint 变长编码 Tag-Len-Val 结构 字段编号不可变 帧 / 流 / 流ID 多路并行无队头阻塞 加密须在帧级别处理 Unary / 一元模式 Server Streaming Client Streaming Bidirectional Streaming 透明加密改造的核心:根据通信模式确定加密点,在正确层级做编解码处理

学完这一章,你应该对gRPC底层有了清晰的认识。Protobuf负责高效打包,HTTP/2负责并行传输,流式模式决定了加密时机。有了这个基础,第三章我们开始动手做真正的加密改造。