前言

  正常情况下,如果需要在运行的程序中增加日志、或者修改部分逻辑,那么我们需要提交代码,重新部署后才能生效,这样做,会给我们增加很多不必要的时间成本。所以,支持热部署的重要性就显而易见了。

  arthas是阿里出品的代码诊断工具,能有效的协助我们进行问题的定位和处理。本文,我们主要讲的是 如何利用arthas来实现代码热部署,利用arthas-boot.jar包或者使用arthas idea插件都能实现。

  注:热部署也算是骚操作了,有风险,不建议在生产环境上操作。

方式一:arthas-boot.jar

运行arthas程序

下载arthas jar包,并启动,然后找到对应的java进程,输入编号进入控制台

1
2
wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar
热部署命令步骤

1,在本地修改好java类,也可以使用jad命令直接在服务器上反编译生成java类后修改,如下:

命令:jad –source-only 类Reference地址 > 反编译文件保存的地址

1
jad --source-only com.test.service.impl.UserServiceImpl > /tmp/arthas/UserServiceImpl.java

2,编译java类,重新生成class字节码文件

命令:mc -d /生成的class文件保存目录 需要生成class文件的java原文件地址

1
mc -d /tmp/arthas /tmp/arthas/UserServiceImpl.java

3,找到jvm里面的classLoaderHash

命令:sc -d -f *类名 | grep classLoaderHash

1
2
3
4
5
sc -d *UserServiceImpl

sc -d *UserServiceImpl | grep classLoaderHash

sc -d -f *UserServiceImpl | grep classLoaderHash

输出:

1
classLoaderHash   18b4aac2 

注:添加 -f 参数可以把类的字段也输出,如:”sc -d -f *类名”。此命令建议不指定grep,这样输出的参数更多,更有助于我们判断加载类是否准确。

4,进行class热部署

命令:redefine -c 【classLoaderHash】 /编译后的class完整路径

1
redefine -c 【替换为classLoaderHash】 /tmp/arthas/UserServiceImpl.class

5,部署完成,可以访问最新内容

6,退出arthas
退出,并未关闭arthas服务,可以重新连接进来

1
按键:q

退出并关闭arthas服务

1
stop 或 shutdown

7,重新链接arthas

1
telnet 127.0.0.1 3658
shell快速生成操作脚本

脚本名称:arthas.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash
#author: chenguolin
p1="$1"

if [ "$1" = "" ];then
echo "请传入:类Reference!如:sh arthas.sh com.test.UserService"
exit 1
fi

echo "----------------------start--------------------------"
echo ""
echo "#####################生成热更新命令##################"
echo ""
echo '1,把class反编译为java类:'
echo 'jad --source-only '$p1' > /tmp/arthas/'${p1##*.}'.java'
echo ""
echo '2,修改java类,并重新编译为class:'
echo 'mc -d /tmp/arthas /tmp/arthas/'${p1##*.}'.java'
echo ""
echo '3,获取类的classLoaderHash:'
echo 'sc -d *'${p1##*.}' | grep classLoaderHash'
echo ""
echo '4,将class热更到jvm中:'
echo 'redefine -c 【替换为classLoaderHash】 /tmp/arthas/'${p1##*.}'.class'
echo ""
echo "----------------------end----------------------------"
echo ""

使用示例:

1
sh arthas.sh com.test.service.impl.UserServiceImpl

生成脚本示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
----------------------start--------------------------

#####################生成热更新命令##################

1,把class反编译为java类:
jad --source-only com.test.service.impl.UserServiceImpl > /tmp/arthas/UserServiceImpl.java

2,修改java类,并重新编译为class:
mc -d /tmp/arthas /tmp/arthas/UserServiceImpl.java

3,获取类的classLoaderHash:
sc -d *UserServiceImpl | grep classLoaderHash

4,将class热更到jvm中:
redefine -c 【替换为classLoaderHash】 /tmp/arthas/UserServiceImpl.class

----------------------end----------------------------

方式二:arthas idea插件

安装idea插件

Idea Plugins插件名称:arthas idea,找到安装即可,重启后 在类或方法上 右键,即可看到相关的arthas命令。

生成热部署脚本

1,代码修改完成后,先执行build recompile命令 进行强制性编译

2,然后,在类名上,点击鼠标右键,选择:Arthas Command >> (hot swap)redefine,生成热部署脚本

3,将拷贝到粘贴板的内容保存到“.sh”可执行文件中,上传到服务器上执行。

当然了,你也可以直接执行此命令,不过命令太长了,不推荐在命令行这么操作,如果你非要问为什么?那你试试就知道了!

执行脚本完成热部署

将.sh脚本上传到服务器后,直接用sh命令运行,即可完成代码热部署!

注意:执行命令的服务器上必须要有jdk环境