项目场景:
是否在项目中使用了RocketMQ ,原本正常的突然某一天提示下方错误,显示序列化失败,启动不起来
问题描述
例如:数据传输过程中数据不时出现丢失的情况,偶尔会丢失一部分数据
APP 中接收数据代码:
c
syntax error, expect {, actual EOF, pos 386, fastjson-version 1.2.83
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:506) ~[fastjson-1.2.83.jar:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseRest(JavaBeanDeserializer.java:1624) ~[fastjson-1.2.83.jar:na]
at com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_1_OffsetSerializeWrapper.deserialze(Unknown Source) ~[na:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:287) ~[fastjson-1.2.83.jar:na]
原因分析:
核心原因是 Fastjson(版本 1.2.83)尝试反序列化一个损坏的本地文件时,没有找到预期的JSON对象起始符 {。这通常与 RocketMQ 存储消费进度(OffsetSerializeWrapper)的 offsets.json 文件损坏有关。
RocketMQ 消费者会在本地生成一个 offsets.json 文件,记录消费进度。如果该文件为空、内容不全或格式错误,Fastjson 就无法正确解析。
错误触发:在错误栈中,FastjsonASMDeserializer_1_OffsetSerializeWrapper.deserialze 表明 Fastjson 正在解析 OffsetSerializeWrapper 对象,这与 offsets.json 文件对应。
解决方案:
第一步:清理本地 RocketMQ 数据文件(推荐首选)
这是最直接有效的方法。直接删除 RocketMQ 在本地存储的所有数据文件。
删除路径:删除用户目录下的 .rocketmq_offsets 文件夹。
Windows:在资源管理器地址栏输入 %USERPROFILE%.rocketmq_offsets 回车,删除该文件夹。
macOS / Linux:在终端执行 rm -rf ~/.rocketmq_offsets。
效果:删除后,RocketMQ 在下次启动时会自动重建该文件,从而绕过损坏的文件。
第二步:配置消费者从最新位置开始消费
如果第一步不彻底,或者希望启动时直接"遗忘"旧的消费进度,可以在创建 RocketMQ 消费者实例时添加以下代码:
java
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("yourGroupName");
// 设置为从队列的"最新"位置开始消费,而不是尝试读取本地记录的位置
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
这会让消费者忽略本地存储的偏移量。
第三步:检查和统一 Fastjson 依赖版本
确保你的项目中 Fastjson 版本是明确且唯一的,以避免因多版本冲突导致解析行为不一致。
检查依赖:在 IDEA 中使用 Maven 或 Gradle 的依赖分析工具,查看项目中 com.alibaba:fastjson 的实际引入版本和来源。
排除冲突:如果你的项目也像之前的搜索建议那样,排除了 RocketMQ 客户端中的 Fastjson 依赖并引入了自己的版本(如 1.2.83),请确保所有模块的版本统一。
第四步:开启 Fastjson 的 SafeMode(可选加固)
此步骤主要针对安全加固,对解决当前文件损坏问题的直接作用有限,但可以作为一项安全措施。你可以在应用启动类中静态代码块里添加以下配置:
java
static {
// 完全禁用 autoType 功能,提升安全性
com.alibaba.fastjson.parser.ParserConfig.getGlobalInstance().setSafeMode(true);
}
⚠️ 注意:根据多所高校的安全通告,1.2.83 版本虽然修复了特定漏洞,但开启 SafeMode 是更彻底的安全防护措施,不过也可能对使用了 autoType 特性的业务代码产生影响。