背景
线上服务升级一天后,大数据过来告诉我说昨天一天的数据大批下滑。
分析
一脸懵逼。昨天升级的服务我是分步升级的,之前的一周我已经升级了1/10的服务,验证业务的稳定,运行一周后,线上无反馈,所以昨天开始批量升级。
我只能把逻辑重新看了一遍,最后锁定再pb新增加了字段如下1
2
3
4
5
6
7
8
9
10
11
12message UserBase
{
optional int32 userid = 1; // 用户ID
optional int32 ip = 2; // IP
optional int32 groupid = 3; // 大厅组ID
optional int32 recommenderid = 4; // 推广(员)ID
optional int32 channel = 5; // 渠道号
optional int32 usertype = 6; // 用户类型( 0:普通用户 1:会员用户)
optional int32 groupopt = 7; // group options
optional string addinfo = 8; // 玩家自定义数据 -- 新增
optional string idcard = 9; // 身份证号 -- 新增
}
按理说pb中新增加字段,没修改序号是没什么影响的,但为什么偏偏出问题了呢?
继续分析,原来是 json->pb 出现的问题。
问题
A服务将pb内容序列化json写入redis1
2
3
4
5
6
7
8
9// bPrimitie false:不输出默认参数, true :输出所有参数
BOOL PB_Msg2Json(const ::google::protobuf::Message& msg, std::string& strJson, bool bMultiLine,bool bPrimitie)
{
google::protobuf::util::JsonPrintOptions jpo;
jpo.add_whitespace = bMultiLine;//multiline 多行显示
jpo.always_print_primitive_fields = bPrimitie; //保留字段是否默认输出
return google::protobuf::util::MessageToJsonString(msg, &strJson, jpo).ok();
}
B服务从redis读取json在序列化为pb1
2
3
4
5
6BOOL PB_Json2Msg(const std::string& strJson, ::google::protobuf::Message& msg)
{
google::protobuf::util::JsonParseOptions jpo;
return google::protobuf::util::JsonStringToMessage(strJson, &msg, jpo).ok();
}
pb新增加了字段,A服务升级,导致redis中的json多了两个字段,这时B服务未升级将json序列为老pb失败。
原因在于PB_Json2Msg 默认的 options 设置问题1
2
3
4
5
6
7BOOL PB_Json2Msg(const std::string& strJson, ::google::protobuf::Message& msg)
{
google::protobuf::util::JsonParseOptions jpo;
jpo.ignore_unknown_fields = true; // 过滤掉json和pb不相同的字段
return google::protobuf::util::JsonStringToMessage(strJson, &msg, jpo).ok();
}