Protobuf 字段演进的坑:reserved 和编号纪律
【摘要】 一次升级事故:同事清理proto文件,删了两个没用的字段,发布提供方。第二天消费端批量报数据错乱——老消息里带着这两个字段的编号,新定义把同编号的数据读成了别的语义。幸好是内部报表,要是资金字段就是资损。Protobuf兼容性的核心规则一句话:兼容性由字段编号加类型决定,字段名随便改,编号永远不能改、不能复用。废弃字段必须用reserved锁住:messageOrder{stringorde...
一次升级事故:同事清理 proto 文件,删了两个没用的字段,发布提供方。第二天消费端批量报数据错乱——老消息里带着这两个字段的编号,新定义把同编号的数据读成了别的语义。幸好是内部报表,要是资金字段就是资损。
Protobuf 兼容性的核心规则一句话:兼容性由字段编号加类型决定,字段名随便改,编号永远不能改、不能复用。废弃字段必须用 reserved 锁住:
message Order {
string order_no = 1;
// 废弃字段锁编号,防未来复用导致老数据错位
reserved 2, 3;
reserved "old_pay_type", "coupon_id";
int32 status_v2 = 4; // 新字段用新编号
string user_id = 5;
}
各类型的兼容边界要记住:int32、int64、uint 系列互相兼容(都按 varint 解析,注意精度);string 和 bytes 兼容;enum 与 int32 兼容,但新增枚举值时老消费端拿到未知值,proto3 里它会落在未识别区间——消费端必须容忍未知枚举并给默认处理;sint、fixed 系列与 varint 系列不兼容,换类型等于换协议;repeated 与标量互不兼容。
实践纪律三条:字段只加不删,废弃用 reserved 占位;proto 文件里维护一张编号台账(注释即可),谁动编号评审必查;破坏性变更直接开新 message 或新方法名,别在同一结构上魔改。二进制的向前向后兼容不是自动的,是编号管理出来的,纪律值多少钱,出一次事故就知道了。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)