- 问题产生背景
Protocol Buffer存储方式:T-L(可选)-V
1. Tag
a. Tag=字段数据类型(wire_type)+标识号(field_number)
b. 占用一个字节的长度(如果标示号超过了16,则占用多一个字节的位子)
c. 反序列化时, Protocol Buffer根据Tag将Value对应于消息中的字段
2. Value(filed_value)
-
问题分析
public class Before {
private Integer A;
private String B;
private BigDecimal C; }public class After {
private Integer A;
private String B;
private String D; private BigDecimal C; }
项目A中最初在Redis中存放的是对象Before, 由于开发新需求, 需要新增字段D, 后续在Redis中存放的是对象After。新功能上线之后,项目A查询历史数据时反序列化字段错位, 即D的值是之前存储的C的值, 而C对应的值是空。因为Protocol Buffer序列化的时候没有存储字段名称(T里面只有filed_number),所以反序列化时也只是按照顺序set值。
-
解决方案
public class After {
private Integer A;
private String B;
private BigDecimal C;
// 新增的字段一定要放到对象的末尾 private String D; }
在此建议,无论之后开发中使用的是哪种序列化方式,对象新增字段的时候一定要追加到末尾!