JDK 序列化问题排查
JDK 序列化问题排查
提供一个线上 JDK 序列化问题排查案例,虽然比较基础,但在我任职的公司中出现过两次,而且是 5 年及以上工作经验的同事写的 bug。供大家参考
新加了个字段,然后发版,上线就发现了报错。
就加了一个字段,怎么就序列化出错了呢?
复现错误
简单定义一个 Yes 类,可以看到就三个字段。
简单 new 了一个对象,直接塞入到 redis 中。
可以看到 value 看起来是乱码,这里用的是 JDK 序列化。
现在我们在 Yes 类加个 hobby 这个字段,然后再从 redis 里面获取之前存入的值然后打印.
看看,是不是报错了,无法反序列化,bug 复现了?
我们再详细看下报错信息,里面有一行字,这就是抛错的具体原因,流里面 serialVersionUID 和本地的 serialVersionUID 不一样的。
为什么会这样?
因为用的是 JDK 序列化,虽然 class 实现了 Serializable 接口但没显示定义 serialVersionUID ,这样一来序列化时会根据当前类的信息计算得到一个 serialVersionUID 。
在序列化存入 redis 后,我又把代码里的 class 的结构变了,这时候再从 redis 获取之前的值反序列化,由于当前的 class 还是没有 serialVersionUID ,于是又会根据当前的类信息计算的 serialVersionUID ,而由于结构变了,类信息肯定变了,所以计算出来的 serialVersionUID 不一致。
因此序列化就失败。
这 serialVersionUID 就好比 class 的版本,版本变了序列化自然就失败了。
解决方式就是显示指定 serialVersionUID,这样就不需要动态计算了。
总结下:如果你了 JDK 序列化,一定记得要加 serialVersionUID ,不然就踩坑了。
还有,不是很推荐用 JDK 序列化,不管是性能还是存储都没有优势。
至于具体选择哪种序列化合适,可以采用比如 Hessian、JSON、Protobuf 等。
以上的排查可以包装成你真正项目上的排查记录,还是很好套的。