服务端把 proto 从 proto2 换到 proto3 重新生成,10% 的老客户端收到消息后数值字段全是 0,字符串字段为空,没有任何报错。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,proto3 不再输出默认值字段,老客户端按必填字段解析时拿不到 key,就用默认值补上。字段编号如果被改过,客户端还会把 A 字段的值读成 B。
「序列化不兼容」这类改动最怕改一半,回滚脚本先准备好,再动生产。别只看报错的最后一行,往上看几行,真正的起因通常在上面。
message Msg {
uint32 ver = 1;
string title = 2;
// 新增字段只能用 3 以后的编号
}
同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
具体做法是,新字段一律用新编号 老编号不要复用也不要删;加版本号字段 服务端按客户端版本做转换;灰度期间同时推 JSON 和 protobuf 两种格式;用旧客户端跑一遍回归 看数值字段是否正常。
最后用这个标准收尾,老版本客户端收到的字段值和之前一致 数值不再是 0。
