Protobuf 让新旧服务仍能沟通
gRPC 的服务端和客户端各自按自己的节奏发布,所以 schema 必须在新旧二进制同时运行时继续演进。Protobuf 正是为此设计的:兼容契约落在字段编号与 wire type 上,而不是字段名上;读方遇到不认识的字段就跳过,而不是失败。 张力在于这份安全既窄又不受强制。能安全做的修改只有一小撮,其余会无声地污染数据,而编译器只拒绝你明确告诉它要拒绝的那些。分清哪次修改属于哪一类,就是全部功夫。 线上说的是编号,不是名字 线上每个字段都是一个 tag——字段编号左移三位再或上 wire type——后面跟着载荷。对 id=7、name=“alpha”、code=1234 这条消息,字节是 08 07 12 05 61 6c 70 68 61 18 d2 09,其中 0x18 标明字段 3 是 varint,d2 09 就是 1234。protoc --encode 产出完全相同的字节,所以这是格式本身,而不是对格式的描述。 因为名字根本不出现在线上,改名是免费的:同一批字节用一份把字段 1 叫 event_id、字段 3 叫 status 的 schema 解出来,值完全一样,只是标签变了。用新编号新增字段同样是安全的——旧读方会把它当作未知编号呈现出来并保留其字节,重新编码能精确复现新消息。正是这份保留,让旧代理可以转发它看不懂的消息。 ...