背景
线上服务升级一天后,大数据过来告诉我说昨天一天的数据大批下滑。
分析
一脸懵逼。昨天升级的服务我是分步升级的,之前的一周我已经升级了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();
}
 
        