Arthas 使用 retransform 热更新 Srping Boot 代码
Arthas Spring Boot 诊断工具 About 7,800 words说明
本文基于Arthas 3.4.6
。
相关代码
package com.example.arthas.controller;
@Slf4j
@RestController
public class Test111Controller {
@GetMapping("/test1")
public Result test1(@RequestParam String key) {
log.info("test1111111111111#{}", key);
List<String> list = (List<String>) CollectionUtils.arrayToList(new String[]{"aaa", "bbb", "ccc"});
return Result.builder().msg("请求成功").data(list).build();
}
}
查看 Arthas 是否已经 attach
已attach
的监听3658
端口。
ss -anpl | grep 3658
已监听,通过telnet
进入。
telnet 127.0.0.1 3658
未监听,通过java -jar
启动。
java -jar arthas-boot.jar
查看类信息
sc
:search class
,-d
:detail
。
找到classLoaderHash
,类加载器的哈希值。
sc -d com.example.arthas.controller.Test111Controller
输出:
[arthas@89537]$ sc -d com.example.arthas.controller.Test111Controller
class-info com.example.arthas.controller.Test111Controller
code-source file:/home/root/demo/arthas-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/
name com.example.arthas.controller.Test111Controller
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name Test111Controller
modifier public
annotation org.springframework.web.bind.annotation.RestController
interfaces
super-class +-java.lang.Object
class-loader +-org.springframework.boot.loader.LaunchedURLClassLoader@7daf6ecc
+-sun.misc.Launcher$AppClassLoader@55f96302
+-sun.misc.Launcher$ExtClassLoader@1ed1993a
classLoaderHash 7daf6ecc
Affect(row-cnt:1) cost in 37 ms.
反编译已加载类的源码
--source-only
:只输出源代码,重定向到/tmp
目录下的Test111Controller.java
文件中。
jad --source-only com.example.arthas.controller.Test111Controller > /tmp/Test111Controller.java
修改代码
vim /tmp/Test111Controller.java
编译反编译过的源码
mc
:Memory Compiler
,-c
:指定类加载的哈希值,-d
:存放.class
文件的文件夹。
mc -c 7daf6ecc /tmp/Test111Controller.java -d /tmp
输出:最终.class
路径位置/tmp/com/example/arthas/controller/Test111Controller.class
。
[arthas@89537]$ mc -c 7daf6ecc /tmp/Test111Controller.java -d /tmp
Memory compiler output:
/tmp/com/example/arthas/controller/Test111Controller.class
Affect(row-cnt:1) cost in 1174 ms.
如果不指定-c
参数,可能出现以下错误。
[arthas@89537]$ mc /tmp/Test111Controller.java -d /tmp
Memory compiler error, exception message: Compilation Error
line: 12 , message: package org.slf4j does not exist ,
line: 13 , message: package org.slf4j does not exist ,
line: 14 , message: package org.springframework.web.bind.annotation does not exist ,
line: 15 , message: package org.springframework.web.bind.annotation does not exist ,
line: 17 , message: cannot find symbol
symbol: class RestController ,
line: 19 , message: cannot find symbol
symbol: class Logger
location: class com.example.arthas.controller.Test111Controller ,
line: 21 , message: cannot find symbol
symbol: class GetMapping
location: class com.example.arthas.controller.Test111Controller ,
line: 19 , message: cannot find symbol
symbol: variable LoggerFactory
location: class com.example.arthas.controller.Test111Controller ,
, please check $HOME/logs/arthas/arthas.log for more details.
热更新
加载外部的 .class 文件,替换原有JVM
已加载的类。
retransform /tmp/com/example/arthas/controller/Test111Controller.class
输出:
[arthas@89537]$ retransform /tmp/com/example/arthas/controller/Test111Controller.class
retransform success, size: 1, classes:
com.example.arthas.controller.Test111Controller
retransform 列表
显示已经替换过的类
retransform -l
输出:
[arthas@89537]$ retransform -l
Id ClassName TransformCount LoaderHash LoaderClassName
1 com.example.art 1 null null
has.controller.
Test111Controll
er
恢复修改前代码
清除掉历史转换过的类,重新触发retransform
以恢复修改之前的代码。
清除指定 retransform
清除id
为1
的entry
。
retransform -d 1
清除所有 retransform
retransform --deleteAll
重新触发 retransform 恢复修改之前的代码
使用--classPattern
匹配需要恢复的代码。
retransform --classPattern com.example.arthas.controller.Test111Controller
输出
[arthas@89537]$ retransform --classPattern com.example.arthas.controller.Test111Controller
retransform success, size: 1, classes:
com.example.arthas.controller.Test111Controller
备注
retransform
过的类,在stop
了Arthas
后不会被reset
,必须手动重新触发retransform
。- 若没有清除
retransform
而停止了Arthas
,则可以再次启动,重新jad
-mc
-retransform
,jad
反编译得到的还是修改前的代码。 retransform
不允许新增加字段或方法。
Arthas 全量文件下载
https://github.com/alibaba/arthas/releases
参考
Views: 4,986 · Posted: 2021-04-27
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...