简介
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字节码
程序的运行也发生改变,这个功能还是很强大,都可以运行中动态调试程序了