当前位置:首页 > 服务端 > 类继承导致 RPC 调用 msgpack 序列化问题分析

类继承导致 RPC 调用 msgpack 序列化问题分析

2022年09月16日 20:44:41服务端7

问题

996 工作态,晚上上线,业务调用方反馈通过 JSF(Jingdong Service Framework)RPC 调用的返回参数异常,获取服务列表的所有服务 service_status 为 0(0 表示已删除)。

分析

系统迅速回滚,返回参数正常。CodeReview 发现 API 的 Vo 父对象新增了属性,而 RPC 传输的子 Vo 继承了父 Vo,虽然,新增的属性是放在父 Vo 的末尾,但为 JSF 的序列化方式为 msgpack,由于业务调用方未更新父 Vo,所以导致了子 Vo 反序列化的异常。

类继承导致 RPC 调用 msgpack 序列化问题分析 _ JavaClub全栈架构师技术笔记

为什么 Vo 的反序列化会失败?而不是像 JSON、Hession 可以向下兼容?

首先,我们要先了解一下 msgpack 的原理。

msgpack

msgpack 用官方的话说,msgpack 是一种高效的二进制序列化方式。

基于官方的解释:JSON 为什么会变小?

类继承导致 RPC 调用 msgpack 序列化问题分析 _ JavaClub全栈架构师技术笔记

核心压缩方式可参看官方说明 messagepack specification:

https://github.com/msgpack/msgpack/blob/master/spec.md

简单的总结下,msgpack 是按字段顺序进行序列化和反序列化的,优点是速度快,缺点是无法改变字段顺序。

msgpack 字段兼容规则

在两边不同时升级的情况下,字段兼容规则如下:(包括 Bean 和枚举)

  • 1、不能调整原有字段顺序,不能删减字段,除非是删最后一个字段

  • 2、新加的字段必须在字段最后面(只是字段顺序,不是文件最后面,getter/setter 方法等随意)

  • 3、父类的字段不能变,因为父类一变相当于子类的中间插入一个字段

满足上面规则,服务端和客户端哪边先升级都无所谓。

如果是需要父类加字段,或者中间加减字段这种,则需要服务端和调用端同时升级。

基于此的理解,我们在看下类继承导致 RPC 调用 msgpack 序列化问题分析:

类继承导致 RPC 调用 msgpack 序列化问题分析 _ JavaClub全栈架构师技术笔记

msgpack VS hessian

Hessian 序列化的时候,会写入字段名称,然后字段值,可以想象为一个 map。

MsgPack 序列化的时候,不写入字段名字,会按字段顺序写入值,可以想象为一个数组。

解决

方案一:Vo 不采用继承,对 Vo 设置 final 属性

方案二:不使用 msgpack 序列化方式,改成 hessian 序列化方式

总结

其实,之前使用 msgpack 序列化方式也出现过类似的问题,如在 Vo 中间新增属性,导致序列化失败,这次的问题之所以没有异常,是因为父 Vo 中新增的属性也是 int 类型,这导致序列化过程中虽然没有赋值,但采用里默认值 0。所以,并没有出现异常,而是结果值错误。

RPC 框架在分布式系统中担任着越来越重要的角色,如阿里的 duboo、京东的 jsf、谷歌的 gRPC,序列化的方式也多种多样,如 json、hessian、msgpack、protobuf 等等,这也需要我们在使用过程中了解其序列化的原理,不断精进。

鸣谢

感谢张松然对本文章的校订。

作者:松然聊技术
来源链接:https://blog.csdn.net/vivisran/article/details/103060507

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/42103.html

分享给朋友:

“类继承导致 RPC 调用 msgpack 序列化问题分析” 的相关文章

吐血整理 《计算机网络 五层协议之物理层(上)》

吐血整理 《计算机网络 五层协议之物理层(上)》

物理层(中篇) 物理层(下篇) 物理层(上篇) 1.物理层的主要功能以及特性 1.1物理层的主要功能 1.2物理层的主要特性...

go系列之利用Gin框架获取form参数

go系列之利用Gin框架获取form参数

利用Gin框架获取form参数 除了通过URL查询参数提交数据到服务器外,常用的还有通过Form表单的方式。Form表单相比URL查询参数,用户体验好,可以承载更多的数据,尤其是文件上传,所以也更为方便。Form 表单对于Form表单,我们不会陌生,比如...

python实现——处理Excel表格(超详细)

python实现——处理Excel表格(超详细)

目录 xls和xlsx 基本操作 1:用openpyxl模块打开Excel文档,查看所有sheet表 2.1:通过sheet名称获取表格...

最容易理解的计算机网络的基础知识概论(上)

最容易理解的计算机网络的基础知识概论(上)

最容易理解的计算机网络基础知识概论(上) 1.计算机网络的分类方法 1)广域网、...

软件工程复习要点

软件工程复习要点

软件工程复习 一、填空题 二、选择题 三、简答题 8.根据一学期的学习,谈谈你对软件工程学科的认识。...

[C#] winform 子窗体向父窗体传值

父窗框mainForm;子窗体childForm,利用事件进行传值在子窗体中的操作: public event EventHandler accept; public string value; private void btnStart_Click(object...

[C#]结构体和字节数组的相互转化

public static class StructCopyer { // 相当于序列化与反序列化,但是不用借助外部文件 //1、struct转换为Byte[] public static Byte[]...

[C#]我自己写的一个对字节中每位进行修改值的函数

位操作方法 代码如下: 1. 设置字节中某位的值 static public Byte s_SetBit(Byte byTargetByte, int nTargetPos, int nValue) { int nValueOfTargetPos = -1...

[Multimedia][TS]TS流的解析

  TS即是"Transport Stream"的缩写。他是分包发送的,每一个包长为188字节。在TS流里可以填入很多类型的数据,如视频、音频、自定义信息等。他的包的结构为,包头为4个字节,负载为184个字节(这184个字节不一定都是有效数据,有一些可能为填充数据)。 工作形式:...

吐血整理《计算机网络五层协议之物理层(下)》

吐血整理《计算机网络五层协议之物理层(下)》

吐血整理《计算机网络五层协议之物理层(上)》 吐血整理《计算机网络五层协议之物理层(中)》 绝知此事要躬行! 物理层(下篇) 1.数字传输系统 1.1PCM的基本原理...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。