RPC调用msgpack序列化问题分析

转发链接:https://blog.csdn.net/wei_wei10/article/details/106693865

问题:

线上业务异常,调用方反馈JSF服务RPC调用异常。读取服务列表服务,所有服务编码均为0(service_code:0)

问题分析:

迅速回滚线上代码,立即止损。在CodeReview过程中,发现API接口中的一个参数属性有变化,JSF 的接口jar做了升级。

这个参数继承了一个父VO,这个父VO增加了一个新的字段(+ statue:int)。JSF的序列化方式为msgpack。业务方未同步更新JSF接口jar包,导致了JSF 反序列化的异常。

为什么反序列化会失败?这个和msgpack有关系。

咱先来看msgpack的官方定义(官网:https://msgpack.org/):

MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it’s faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.

从官方定义中可以得出以下结论:

首先它是一种二进制序列化格式。
它允许跨语言交换数据。
性能上,它比json序列化性能要好。
体积上,它比json序列化体积要小。

以上是msgpack的优点,但是在接受它的优点的同时,必须同时接受它的缺点。

其中一个缺点是无法改变字段顺序。

对,无法改变字段顺序。线上JSF调用,反序列化异常就是因为这个原因。序列化的对象,顺序被改变了。

我找来了一个官方的一个示例说明,这个例子里解释了为什么序列化后内容体积会变小。

可以看到,msgpack序列化结果,只有value!并且value进行了专属映射。

(官方说明书:https://github.com/msgpack/msgpack/blob/master/spec.md)

再来个直观对比:

msgpack是不是让人又爱又恨。选用msgpack就是为了效率,咱来了解一下兼容规则。

在两边不同时升级的情况下,字段兼容规则如下:

不能调整原有字段顺序,不能删减字段。最后一个字段除外。
新增的字段必须在字段最后。
父类字段不能改变,因为父类改变等于在子类中间插入了一个字段。

如果违反上面👆任意一条,必须RPC客户端与服务器同时升级。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值