仅客户端-服务器通信场景下,移除Protobuf字段是否会引发问题?
Protobuf官方文档指出:删除字段若操作不当会引发严重问题。当不再需要某个字段且客户端代码已移除所有引用时,可删除消息中的字段定义,但必须保留该字段编号,否则未来开发者可能会复用该编号。
即便你的场景是单客户端、单服务器且两端同步更新,移除字段或重排字段编号依然可能引发这些问题:
遗留缓存/历史数据解析错误
客户端或服务器可能缓存了旧的序列化Protobuf数据(比如本地存储的请求记录、日志里的抓包数据),更新proto文件后,用新的结构去解码这些旧数据时,会出现字段映射错误。比如旧proto里字段2是user_id,重排后字段2变成order_id,解码旧数据时会把原本的user_id值当成order_id处理,直接导致业务逻辑异常。部署间隙的版本不一致
哪怕约定同步更新,实际部署时难免存在时间差:比如服务器先完成更新,客户端还在重启部署中,这期间旧客户端发送的请求用的是旧字段编号,新服务器解析时就会出现数据错乱;反过来客户端先更,服务器未更也会有同样问题。这种短暂的不一致窗口很容易引发线上故障。调试排查障碍
线上出现问题时,你需要回溯历史日志或抓包数据定位原因。如果字段编号被修改或删除,新的proto文件无法正确解析这些历史数据,你没法还原当时的请求内容,排查问题的难度会大幅提升。Protobuf的隐式解析行为坑
Protobuf解码时会忽略未定义的字段,但如果是重排编号,旧数据里的字段值会被错误匹配到新的同编号字段。比如旧字段1是username(字符串类型),新字段1是age(整数类型),解码时字符串会被强制转成整数,要么得到错误数值,要么直接抛出解析异常,这种问题隐蔽性强,测试阶段不容易覆盖到。
内容的提问来源于stack exchange,提问作者Ahmet Yazıcı

