漫画:Java如何实现热更新?






Arthas(阿尔萨斯)是 Alibaba 开源的一款 Java 确诊东西,运用它咱们能够监控和排查 Java 程序,但是它还供给了十分实用的 Java 热更新功用。
所谓的 Java 热更新是指在不重启项目的状况下完成代码的更新与替换。运用它能够完成不停机更新 Java 程序,尤其是对那些发动十分耗时的 Java 项目来说,更是效果显著。
Arthas 的运用其实十分简略,它为咱们供给了一个 Jar 包,咱们只需求把这个 JI [ :ar5 T = P A 下载到1 + 7 Q 4本地,然后运转这个 Jar 包就能够正常运用它的功用了。
Arthas 功用简述
当0 M w P R D [你遇到以下类似问题而束手无策时,Arthas 能够协助你解决(来自官方):
- 这个类从哪个 jab 8 t 1 E % # p yr 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码: K { ] 7 : w为什么没有履行到?莫非是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,莫非只能经过加日志再从头发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否N $ P 4 # 0 k有一个全局视角来检查体系的运转状况?
- 有什s 0 Y % T么办法能够监控到JVM的实时运转n 9 , i U ) 1状况?
- 怎么快速定位应用的热点,生成火焰图?
Ab n % f W ^ Brthas 支撑 JDK 6+,支撑 Linux/Mac/Winodws,它选用指令行交互g Z A X 9 K ^ E c形式,一起供给丰厚的 T6 S #ab 主动补全功用,进一步便利进行问题的定位和确诊。
Arthas 运用
Arthas 的运用过程如下。
过程一:下载 Arthas
首要,咱们先把 Arthas 的 Jar 包下载到本地,它的下载地址是:alibaba.github.io/arthas/arta L ? [h…
过程二:发动 Arthas
咱们x I N d ( U只需求运用普通的 jC T C z 9 n `ar 包发动指令:java -jar arthas-boot.jar
来发动 Arthas 即可,发动成功之后的运转界面如下:

如上图所示则表明 Arthas 发动成功。
小贴士:当咱们运转 java -jar arthas-boot.jar 指令时,首要需求先切换目录至该 jar 包的方位,r ( w k &才干正常的发动 Arthas。
过x X M程三:运转 Arthas
当咱们发动完 Arthas 之后,根据上图的提示,咱们需求挑选一个要调试的 Java 进程,例如咱们输入“4”来监测我自己写的一个 Java 测验程序,履H # m S M $ =行成果如下:

当呈现 Ar i Z ` 3 S 6 ^ Mthas 的Q O + logo[ D / s – s C 之后,表明 Arthas 正常加载了 Jav| G & B ] f ya 进程。
过程四:操作 Arthas
当 Arthas 加载 Java 进程成功之后,咱们就能够输入相关的指令来检查相关的信息了。
假设咱们把本地环境视为生产服务器,咱们此刻需求检查某个运转的 Java 程序是否为最新L ! w + U . 5 [ 2版的。
在没有 Arthas 之前,咱们通常的B t 6 d P : n y m过程是这样的:
- 找到相应的 jar 包(或许 war 包);
- 将H 2 q y @ A x jarF y f = u f * 包(或许 war 包)下载到本H C @ F 2 9 3地;
- 找出相应的类进行解压操作;
- 然后将解压的 class 文件拖拽到 Java 编译; 4 | : ?器(Idea 或 Eclipse)中,检查是否为最新的代码。
但假设运用的是 Arthas,那么咱们就能够直接7 U b 9 x K 9 /经过反编译指令,将字节码编译为正常的 Java 代码,然后再确认是否为最新的代码即可。咱们只需求履行 jad
指令即可,完成示例如下:

这样咱们就能够直接来检查这个发布的程序是否为最新版别了。 3 @ W * D n q
不仅如此,咱们还能够运用 Arthas 来监测整个程序的I n F {运转状况,如下图所示:

咱们还能够用 Arthas 来检查一些 JVM 的相关信息,如下u ; * + Z [ 8 6图所示:

更多 A{ J Jrthas 的功用请访问:alibaba.github.io/arthas/comm…
热更q . _新 Java 代码


假设咱们原来的代码是这样的:
pa{ c @ : V ! =ckage com.examp6 u n b 4 ` x a ole;
import java.util.concurrent.TimeUnit;
public class Ar + 9 X g L Dpp {
public static void ma- { p u m G $ + Hin(String[] args) throws Interrupteb i R S i a * R %dException {
while (true) { // 每两秒钟打印一条信息
TimeUnit.% ` q O ` 5 o ;SECONDS.sl~ y F 2 w v y e jeep(3);
sayHi();
}
}
private static void s` m 6ayHi() {
// 需求i ; i } c H =修正的标识
boolean flag = true;
if (flag) {
System.out.println("Hello,Java.");
} else {
System.out.println("Hello,Java中文社群.");
}
}
}
咱们现在想要把 flag
变量改为 fk v K ? [alse
就能够这样来做:
- 运用 Arthas 的内存编译东西将新的 Java 代码编译为字节码;
- 运用 Arthas 的
r) ; Y / Vedefine
指令完成热更新。
1.编译字节码
首要,咱们需求将新的 Java 代码编译为字节码,咱们能够经过 Arthas 供给的 mc
指令完成,mc
是 Memory Compiler(内存编译器)的缩写。
完成示例如下:
[artb q B } ` k Y uhas@3478]$ mc /Users/admin/Desktop/App.java -d /Users/admin/Desktop
Memory compiler output:
/Users/* % Vadmin/Desktop/D 5 P q 7 2 ? [ Xcom/example/App.c_ x F _ ? T # !lass
Affect(row-cnt:1) cost in 390 ms.
其中 -d
表明编译文件的存放方位。
小g R B n S v B ` L贴士:咱们也能够运用 javac App.java 生成的字节码,它与此过程履行的成果相同。
2.履行热更新
有了字节码文件之后,咱们就能够运用 redefine
指令来完成热更新了,完成示例如下:
[a^ Y i W & R Jrthas@51l ` z 7 ] , Z ` b787]$ redefine /UserB = 8s/admin/Desktop/com/example/App.class
redefine success, s@ 5 ` ? k m xize: 1
从上述成果能够看出,热更新履行成功,此刻咱们去控制台检查履行成果,如下图所示:

这说明热更新履行确实成功了。
Arthas 热更新注意事项
运用热更新功用有一些条件限制,咱们只能用它来修正办法内部的一些业务代码,假设咱们呈现了4 j f D ` #以下任意一种状况,那么热更新就会履行失利:
- 添加类特点(类字段);
- 添加或删去办法;
- 替换正在运转的办法。
最后一条咱们需求单独说明一下,假设咱们把上面的示例改为v E l U 0如下代码:
package com.example;
import java.util.concurrent.TimeUnit;
public class App {
public static void main(String[] args) throws InterruptedException {
while (true) { // 每两秒钟打印一条信息
TimeUnit.SECONDS.sleep(3);
boolean flag = true;
if (flag) {
System.out.println("Hello,Java.");
} else {
System.out.println("Hello,Java中文S i b q p + ) Y社群.");
}
}
}
}
那么此刻咱们再进行热更新操作修正 flag
的值,那么就会履行失利,因为咱们替换的是正在运转中的办法,而咱们正常^ C V q示例中的代码之所以能成功,是因为咱们在 while
无= % b线循环中调用了另一个办法,而那个办法是被间歇4 y G性运用的,因此能够替换成功。
总结e [ # X G ^ :
本文咱们讲了 Arthasq 5 Y 的概念以及详细的运用流程,Arthas 其a B 6 w ) ~ p实便是一个普通的 Java 程序,咱们能够运用 java -jar arthas-boot.jar
来发动它,然后再挑选咱们要操: ^ e作的 JavE S Ua 进程,这样就能够完成状况监X U p H `控和其他操作。
文章的后半部分,咱们介绍了 Arthas 的热更新功用,而热更新本质上X Y z J u P i只需求运用一个 redefine
指令来加载新的字节码文件就能够完成热更新了,但需求注意热更新不能替换正在运转的办法,它只能修正办法内部的业务代码,假设修正了类字段或许是更改了类办法,那么热更新就会V V H R l d f U 8履行失利。
关注公众号「Java中文社群b ? E 5」回复“干货”,获% A p _ ? H取 50 篇原创干货 Top* . j d ~ H ) B 榜。
