从利用Arthas排查线上Fastjson问题到Java动态字节码技术(上)

本文通过一个线上问题复盘,讲述了在重构过程中遇到的Fastjson反序列化错误,由于类信息变更导致缓存数据无法正确解析。通过Arthas工具在线查看源码、编辑并热部署,成功定位和解决问题。强调了测试和理解代码细节的重要性,并介绍了Arthas在Java应用诊断中的实用功能。
摘要由CSDN通过智能技术生成

没被Fastjson搞过的程序员不是合格的程序员 ---- 手动狗头
开个玩笑,福报厂的同学们不要喷,Fastjson是非常优秀的工具!

复盘

先简短复盘下之前遇到的一个线上问题:随着业务发展项目A日渐臃肿,已经成为人人都头疼的big ball of mud 大泥球,遂决定对其进行重构,细节包括服务拆分与部分逻辑重构。虽然我不是这块业务的技术owner,但这类重构任务自然还是我来负责,同时在业务需求排队与原owner看戏心态的情况下,留给我从头熟悉与重构的时间并不多… 重构过程就不在这赘述了,虽然发现和解决了很多问题,但还算顺利,这中间花费时间最多的就是测试,读过老马的书或真正参与过重构的同学都知道,任何重构都建立在测试的基础上,没有单元测试、集成测试、回归测试,都是在自寻死路… 所以当我拿到项目A源码看到那空空的test文件夹时,我陷入了沉思… 但还是要硬着头皮上的,做了各种我认为有必要的测试… 时间来到了上线那一天,问题还是出现了… 问题是由新项目无法使用fastjson反序列化线上redis缓存数据导致的… 百密一疏,功亏一篑,在本地与测试环境做了N种测试,但并没考虑到线上redis缓存中还有部分老数据…

大厂的同学们都很喜欢搞脚手架,喜欢在开源工具上包装,原项目A中缓存部分就有这么一个Redis缓存脚手架工具;脚手架如果设计的好那么可以大幅提高开发效率,但如果设计的不好那对于使用者来说就是黑盒的!

这个Redis工具在序列化的时候使用json格式来做存储,使用的是Fastjson;而Fastjson在序列化Redis对象的时候,会记录class信息,所以一旦class信息对不上,那么序列化反序列化就会失败…

public class GenericFastJsonRedisSerializer implements RedisSerializer<Object> {
   
	/** 略 */
    public byte[] serialize(Object object) throws SerializationException {
   
        if (object == null) {
   
            return new byte[0];
        }
        try {
   
            return JSON.toJSONBytes(object, SerializerFeature.WriteClassName);
        } catch (Exception ex) {
   
            throw new SerializationException("Could not serialize: " + ex.getMessage(), ex);
        }
    }
	/** 略 */
}

虽然缓存功能也包含在测试范围内了,但不清楚这个脚手架的细节让我还是掉坑里了…

Anyway,吃一堑长一智,这就是成长啊 ---- 狗头

重现

做个最简单的demo来重新这个问题:

@SpringBootApplication
public class DemoApplication {
   

	public static void main(String
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值