方块糖的工坊
方块糖的工坊

利用Arthas热更新SpringBoot项目

前言

线上程序逻辑有严重bug!用户现场没有网络不好导入新包!!不能重启系统!!!
遇到这种场景你是不是已经汗流浃背,准备提桶跑路了~
不要慌,我们祭出神器 Arthas

需求

Arthas 修改热更的逻辑主要分为三步:

  • jad 命令反编译出内存中的字节码,生成 java 文件
  • 修改代码,使用 mc 命令内存编译新的 class 文件
  • redefine 重新加载新的 class 文件

流程

构造错误代码

如下图,通过一个接口计算斐波那契数列,我们故意把+号改成了*号

image-20240521160031353

打包测试一下,果然,输出结果是错误的(正确结果应该是3)

image-20240521161934558

启动Arthas

将Arthas拷贝到服务器(如果是你的服务跑在容器里,记得要把他再拷贝到容器内)

https://cdn.guitang.fun/Blog/20240522091516.png

反编译出源码

使用 sc 命令查找类,记住下图箭头所指两个参数

sc -d *ApiController
https://cdn.guitang.fun/Blog/20240522092103.png

使用如下命令得到 ApiController 的源码

jad --source-only com.example.controller.ApiController > /tmp/ApiController.java

编译源码

通过vim或编辑器修改源码

https://cdn.guitang.fun/Blog/20240522092842.png

使用mc命令编译源码(-c 后面的参数是我们第一步通过 sc 命令得到的)

mc -c 254989ff /tmp/ApiController.java -d /tmp

解决编译报错

报错了

https://cdn.guitang.fun/Blog/20240522094402.png

网上也找了一些教程,大家都说 mc 容器出错,但没给出为什么,而是让我们通过IDE编译得到class文件,这与我们的初衷不符

其实呢,问题出在jad命令上,通过jad生成的源码不一定是正确的,我们仔细看下报错,定位到397行

https://cdn.guitang.fun/Blog/20240522100732.png

可以看到 jad 反编译得到的源码确实有问题,而且和IDE中的真实源码也有出入,那我们手动改下 jad 源码内容

挂载新class

然后重新执行 mc 命令,成功了!紧接着执行最后一步 redefine 热更新代码

redefine /tmp/com/example/controller/ApiController.class
https://cdn.guitang.fun/Blog/20240522102311.png

验证下接口

https://cdn.guitang.fun/Blog/20240522101340.png

热更新成功~

发表回复

textsms
account_circle
email

方块糖的工坊

利用Arthas热更新SpringBoot项目
前言 线上程序逻辑有严重bug!用户现场没有网络不好导入新包!!不能重启系统!!!遇到这种场景你是不是已经汗流浃背,准备提桶跑路了~不要慌,我们祭出神器 Arthas。 需求 Art…
扫描二维码继续阅读
2024-05-22