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