利用Arthas热更新SpringBoot项目

1,381次阅读
没有评论

共计 808 个字符,预计需要花费 3 分钟才能阅读完成。

前言

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

需求

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

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

流程

构造错误代码

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

利用Arthas热更新SpringBoot项目

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

利用Arthas热更新SpringBoot项目

启动Arthas

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

利用Arthas热更新SpringBoot项目

反编译出源码

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

sc -d *ApiController
利用Arthas热更新SpringBoot项目

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

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

编译源码

通过vim或编辑器修改源码

利用Arthas热更新SpringBoot项目

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

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

解决编译报错

报错了

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

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

利用Arthas热更新SpringBoot项目

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

挂载新class

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

redefine /tmp/com/example/controller/ApiController.class
利用Arthas热更新SpringBoot项目

验证下接口

利用Arthas热更新SpringBoot项目

热更新成功~

正文完
 1
评论(没有评论)