Java 诊断利器-Arthas的基本使用

简介

Arthas 是阿里巴巴最近才开源出来的一款 Java 诊断利器,它主要是针对线上环境,能够帮助我们更好的定位问题。
Case:https://github.com/alibaba/arthas/issues?q=label%3Auser-case
官方文档: https://alibaba.github.io/arthas
官方文档还是比较详细的,这里就挑几个觉得好用的来实操一下

实操

在这里插入图片描述
下载好后,目录是这样的,win运行bat脚本即可, as.bat +
在这里插入图片描述
pid可以通过jps命令找出来

package com.bfxy.springboot;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Demo {
    
    
    private static AtomicInteger count = new AtomicInteger(0);
    public static void increment() {
    
    
        count.incrementAndGet();
    }
    public static int value() {
    
    
        return count.get();
    }
    public static void main(String[] args) throws InterruptedException {
    
    
        while (true) {
    
    
            increment();
            System.out.println("counter: " + value());
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

然后写了个demo,attach上去
在这里插入图片描述
就到了启动界面

watch

方法执行数据观测
让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。
在这里插入图片描述
在这里插入图片描述
输入watch命令,监视Demo类中的value方法的返回值
在这里插入图片描述
发现跟这个是对应的,监控有效!
在这里插入图片描述
表达式使用”{params,returnObj}”,表示将入参和返回值打印出来,这里没有入参,result中的第一个@Object为空

trace

方法内部调用路径,并输出方法路径上的每个节点上耗时
trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
在这里插入图片描述
查看调用increment方法的链路耗时
在这里插入图片描述
也可以使用通配符监控所有方法

sc

查看JVM已加载的类信息
“Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,这个命令支持的参数有 [d]、[E]、[f] 和 [x:]。

在这里插入图片描述
在这里插入图片描述
打印出了类的详细信息,看case里面,通过这种方法可以更好的判断NoSuchMethodError的原因

jad

反编译指定已加载类的源码
jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑;

redefine

加载外部的.class文件,redefine jvm已加载的类。
注意, redefine后的原来的类不能恢复,redefine有可能失败(比如增加了新的field),参考jdk本身的文档。

这个命令可以结合上面的jad命令一起使用,当需要调试正在运行的程序时,先jad反编译,然后修改了再redefine上去

redefine实战日志打印捕获

这也是根据里面的case学到的

背景:
随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如:
在这里插入图片描述
这个程序是一个短信发送程序,由于连接不上ISMG网关而报的错误,使用的短信开发包比较老,是直接在控制台打印的,都没有使用日志,有点坑,这样看起来就比较烦了,都不知道从哪里打印的这个,找源码又太慢,现在使用Arthas来解决它

在java代码里,字符串拼接基本都是通过StringBuilder来实现的,所以把StringBuilder复制下来,然后在toString方法中修改一下

    @Override
    public String toString() {
    
    
        // Create a copy, don't share the array
        String result = new String(value, 0, count);
        if(result.contains("Connection refused")) {
    
    
            System.err.println(result);
            new Throwable().printStackTrace();
        }
        return result;
    }

这里加上一个判断,为异常字符串中的就打印出堆栈
然后javac StringBuilder.java编译
在这里插入图片描述
还是attach上这个程序后,通过redefine命令去修改StringBuilder字节码
在这里插入图片描述
程序的运行也发生改变,这个功能还是很强大,都可以运行中动态调试程序了

猜你喜欢

转载自blog.csdn.net/w57685321/article/details/84307516