arthas最实用功能

热更新代码

下面介绍通过jad/mc/redefine 命令实现动态更新代码的功能。

目前,访问 http://localhost/user/0 ,会返回500异常:

curl http://localhost/user/0
{"timestamp":1550223186170,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}

下面通过热更新代码,修改这个逻辑。

jad反编译UserController

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java

jad反编译的结果保存在 /tmp/UserController.java文件里了。

再打开一个Terminal 3,然后用vim来编辑/tmp/UserController.java

vim /tmp/UserController.java

比如当 user id 小于1时,也正常返回,不抛出异常:

    @GetMapping(value={"/user/{id}"})
    public User findUserById(@PathVariable Integer id) {
        logger.info("id: {}", (Object)id);
        if (id != null && id < 1) {
            return new User(id, "name" + id);
            // throw new IllegalArgumentException("id < 1");
        }
        return new User(id.intValue(), "name" + id);
    }

sc查找加载UserController的ClassLoader

sc -d *UserController | grep classLoaderHash
$ sc -d *UserController | grep classLoaderHash
 classLoaderHash   1be6f5c3

可以发现是 spring boot LaunchedURLClassLoader@1be6f5c3 加载的。

mc

保存好/tmp/UserController.java之后,使用mc(Memory Compiler)命令来编译,并且通过-c参数指定ClassLoader:

mc -c 1be6f5c3 /tmp/UserController.java -d /tmp
$ mc -c 1be6f5c3 /tmp/UserController.java -d /tmp
Memory compiler output:
/tmp/com/example/demo/arthas/user/UserController.class
Affect(row-cnt:1) cost in 346 ms

redefine

再使用redefine命令重新加载新编译好的UserController.class

redefine /tmp/com/example/demo/arthas/user/UserController.class
$ redefine /tmp/com/example/demo/arthas/user/UserController.class
redefine success, size: 1
-- 重新加载多个
redefine -c 327a647b /tmp/Test.class /tmp/Test\$Inner.class

获取容器并执行方法

tt -i 1000 -w 'target.getApplicationContext()'
$ tt -i 1000 -w 'target.getApplicationContext()'

@AnnotationConfigEmbeddedWebApplicationContext[
    reader=@AnnotatedBeanDefinitionReader[org.springframework.context.annotation.AnnotatedBeanDefinitionReader@2e457641],
    scanner=@ClassPathBeanDefinitionScanner[org.springframework.context.annotation.ClassPathBeanDefinitionScanner@6eb38026],
    annotatedClasses=null,
    basePackages=null,
]
Affect(row-cnt:1) cost in 439 ms.

获取spring bean,并调用函数

tt -i 1000 -w 'target.getApplicationContext().getBean("scheduledTask03").run()'

线程信息

1. 查看所有线程信息

thread

2. 查看具体线程的栈

查看线程ID 16的栈:

thread 16

3. 查看CPU使用率top n线程的栈

thread -n 3

查看5秒内的CPU使用率top n线程栈

thread -n 3 -i 5000

4. 查找线程是否有阻塞

thread -b

实时修改logger级别

1. 查看logger信息

logger

2. 修改logger级别

logger --name ROOT --level error
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值