一次线上升级大规模报错后,我又重新学习了序列化!
2020/3/31 17:02:13
本文主要是介绍一次线上升级大规模报错后,我又重新学习了序列化!,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
背景
去年9月份时候fastjson出现过一个漏洞,需要升级到1.2.60,旧版本是1.2.12,测试环境验证完毕后上线,上线几分钟瞬间几百封报错邮件,当时瞬间心里特紧张,但是表面上得装着没事,咱能搞定,哈哈,还好迅速定位并解决了问题。
系统流程
出问题模块流程比较简单,需要查询一些数据,先从Redis查询,没有再查询数据库并把结果放到Redis中缓存。
问题排查
报错异常信息如下:
java.io.InvalidClassException: com.alibaba.fastjson.JSONObject; local class incompatible: stream classdesc serialVersionUID = -7894253080042154647, local class serialVersionUID = 1 复制代码
看到报错可能你已经明白了,反序列化时候版本不一致导致的问题,那么问题是如何产生的呢?
Fastjson1.2.60源码的JSONObject类里有下面一行代码:
private static final long serialVersionUID = 1L; 复制代码
而1.2.12版本源码的JSONObject类里没有定义serialVersionUID。
Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的,在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常
当实现java.io.Serializable接口的类没有显式地定义一个serialVersionUID变量时候,Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果Class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释等等),就算再编译多次,serialVersionUID也不会变化的。
问题原因找到了,系统返回实体里存放了JSONObject的对象,系统上线后用户访问时候如果缓存有数据,就会出现反序列化版本不一致的情况,导致出现异常。
解决方案
先说下我的方案,使用新版本的jar包,把设置缓存代码里key的前缀修改下,这样就不会使用旧的缓存进行反序列化,问题解决。
例如:
//原始代码 @CacheEvict(value="RedisCache11",key="'user:test:'+#obj.id",beforeInvocation=true) //修改后代码 @CacheEvict(value="RedisCache11",key="'user:test2020:'+#obj.id",beforeInvocation=true) 复制代码
以上是我的一种的解决方案,如果你有其他的方案,欢迎留言沟通哦!
推荐阅读
5.原创 | 我是如何解决POI解析Excel出现的OOM问题的?
如果觉得文章不错,希望可以随手转发或者”在看“哦,非常感谢哈!
关注下方公众号后回复「1024」,有惊喜哦!
这篇关于一次线上升级大规模报错后,我又重新学习了序列化!的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?