前言
线上程序逻辑有严重bug!用户现场没有网络不好导入新包!!不能重启系统!!!
遇到这种场景你是不是已经汗流浃背,准备提桶跑路了~
不要慌,我们祭出神器 Arthas。
需求
Arthas 修改热更的逻辑主要分为三步:
- jad 命令反编译出内存中的字节码,生成 java 文件
- 修改代码,使用 mc 命令内存编译新的 class 文件
- redefine 重新加载新的 class 文件
流程
构造错误代码
如下图,通过一个接口计算斐波那契数列,我们故意把+号改成了*号
打包测试一下,果然,输出结果是错误的(正确结果应该是3)
启动Arthas
将Arthas拷贝到服务器(如果是你的服务跑在容器里,记得要把他再拷贝到容器内)
反编译出源码
使用 sc 命令查找类,记住下图箭头所指两个参数
sc -d *ApiController
使用如下命令得到 ApiController 的源码
jad --source-only com.example.controller.ApiController > /tmp/ApiController.java
编译源码
通过vim或编辑器修改源码
使用mc命令编译源码(-c 后面的参数是我们第一步通过 sc 命令得到的)
mc -c 254989ff /tmp/ApiController.java -d /tmp
解决编译报错
报错了
网上也找了一些教程,大家都说 mc 容器出错,但没给出为什么,而是让我们通过IDE编译得到class文件,这与我们的初衷不符
其实呢,问题出在jad命令上,通过jad生成的源码不一定是正确的,我们仔细看下报错,定位到397行
可以看到 jad 反编译得到的源码确实有问题,而且和IDE中的真实源码也有出入,那我们手动改下 jad 源码内容
挂载新class
然后重新执行 mc 命令,成功了!紧接着执行最后一步 redefine 热更新代码
redefine /tmp/com/example/controller/ApiController.class
验证下接口
热更新成功~
发表回复