Alibaba Java诊断工具Arthas之快速安装和简单使用

Alibaba Java诊断工具Arthas简单介绍 :

当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

1.这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
2.我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
3.遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
4.线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
5.是否有一个全局视角来查看系统的运行状况?
6.有什么办法可以监控到JVM的实时运行状态?

Arthas支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

一、快速安装

这里我们使用官网推荐的arthas-boot

下载arthas-boot.jar,然后用java -jar的方式启动:

 wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar

打印帮助信息:

 java -jar arthas-boot.jar -h

二、简单使用

1.下载官方提供的Demo并启动

arthas-demo是一个简单的程序,每隔一秒生成一个随机数,再执行质因式分解,并打印出分解结果。

 wget https://alibaba.github.io/arthas/arthas-demo.jar
java -jar arthas-demo.jar

2.重新java -jar启动下载好的arthas jar包

 java -jar arthas-boot.jar

启动完将看到:

 ➜  githubTools java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.1.0
[INFO] Found existing java process, please choose one and hit RETURN.
* [1]: 6419 arthas-demo.jar
[2]: 823

3.选择应用java进程

Demo进程是第1个,则输入1,再输入回车/enter。Arthas会attach到目标进程上,并输出日志:

 [INFO] arthas home: /Users/zhangboqing/.arthas/lib/3.1.0/arthas
[INFO] Try to attach process 6419
[INFO] Attach process 6419 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----' wiki: https://alibaba.github.io/arthas
version: 3.1.0
pid: 6419
time: 2019-02-16 23:22:11 $

这样就进入到对应的进程中了,接下来的操作都是在当前进程中的

3.简单命令介绍

1)dashboard
输入dashboard,按回车/enter,会展示当前进程的信息,按ctrl+c可以中断执行。

 ID             NAME                                         GROUP                         PRIORITY      STATE          %CPU           TIME           INTERRUPTED    DAEMON
21 Timer-for-arthas-dashboard-b47de3b0-268b-4d6 system 10 RUNNABLE 76 0:0 false true
15 nioEventLoopGroup-3-1 system 10 RUNNABLE 23 0:0 false false
11 AsyncAppender-Worker-arthas-cache.result.Asy system 9 WAITING 0 0:0 false true
9 Attach Listener system 9 RUNNABLE 0 0:0 false true
3 Finalizer system 8 WAITING 0 0:0 false true
2 Reference Handler system 10 WAITING 0 0:0 false true
4 Signal Dispatcher system 9 RUNNABLE 0 0:0 false true
19 as-command-execute-daemon system 10 TIMED_WAITING 0 0:0 false true
13 job-timeout system 9 TIMED_WAITING 0 0:0 false true
1 main main 5 TIMED_WAITING 0 0:0 false false
14 nioEventLoopGroup-2-1 system 10 RUNNABLE 0 0:0 false false
18 nioEventLoopGroup-2-2 system 10 RUNNABLE 0 0:0 false false
16 pool-1-thread-1 system 5 TIMED_WAITING 0 0:0 false false
17 pool-2-thread-1 system 5 WAITING 0 0:0 false false Memory used total max usage GC
heap 39M 123M 1820M 2.16% gc.ps_scavenge.count 3
ps_eden_space 28M 32M 672M 4.20% gc.ps_scavenge.time(ms) 32
ps_survivor_space 4M 5M 5M 99.38% gc.ps_marksweep.count 0
ps_old_gen 6M 85M 1365M 0.45% gc.ps_marksweep.time(ms) 0
nonheap 19M 20M -1 96.34%
code_cache 4M 4M 240M 1.78%
metaspace 13M 13M -1 96.48%
compressed_class_space 1M 1M 1024M 0.16%
direct 0K 0K - Infinity%
Runtime
os.name Mac OS X
os.version 10.14
java.version 1.8.0_112
java.home /Library/Java/JavaVirtualMachines/jdk1.8.0_1
12.jdk/Contents/Home/jre
systemload.average 1.69
processors 4

2)thread

通过thread命令来获取到arthas-demo进程的Main Class
thread 1会打印线程ID 1的栈,通常是main函数的线程。

 $ thread 1
"main" Id=1 TIMED_WAITING
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at demo.MathGame.main(MathGame.java:17) Affect(row-cnt:0) cost in 17 ms.

3)jad

通过jad来反编译Main Class

 $ jad demo.MathGame

 ClassLoader:
+-sun.misc.Launcher$AppClassLoader@6bc7c054
+-sun.misc.Launcher$ExtClassLoader@7e97d617 Location:
/Users/zhangboqing/Software/githubTools/arthas-demo.jar /*
* Decompiled with CFR 0_132.
*/
package demo; import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit; public class MathGame {
private static Random random = new Random();
public int illegalArgumentCount = 0; public static void main(String[] args) throws InterruptedException {
MathGame game = new MathGame();
do {
game.run();
TimeUnit.SECONDS.sleep(1L);
} while (true);
} public void run() throws InterruptedException {
try {
int number = random.nextInt() / 10000;
List<Integer> primeFactors = this.primeFactors(number);
MathGame.print(number, primeFactors);
}
catch (Exception e) {
System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage());
}
} public static void print(int number, List<Integer> primeFactors) {
StringBuffer sb = new StringBuffer("" + number + "=");
Iterator<Integer> iterator = primeFactors.iterator();
while (iterator.hasNext()) {
int factor = iterator.next();
sb.append(factor).append('*');
}
if (sb.charAt(sb.length() - 1) == '*') {
sb.deleteCharAt(sb.length() - 1);
}
System.out.println(sb);
} public List<Integer> primeFactors(int number) {
if (number < 2) {
++this.illegalArgumentCount;
throw new IllegalArgumentException("number is: " + number + ", need >= 2");
}
ArrayList<Integer> result = new ArrayList<Integer>();
int i = 2;
while (i <= number) {
if (number % i == 0) {
result.add(i);
number /= i;
i = 2;
continue;
}
++i;
}
return result;
}
} Affect(row-cnt:1) cost in 830 ms.
$

4)watch

通过watch命令来查看demo.MathGame#primeFactors函数的返回值:

 watch demo.MathGame primeFactors returnObj
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 59 ms.
ts=2019-02-16 23:31:38; [cost=1.710847ms] result=null
ts=2019-02-16 23:31:39; [cost=0.079354ms] result=null
ts=2019-02-16 23:31:40; [cost=0.251734ms] result=@ArrayList[
@Integer[2],
@Integer[2],
@Integer[2],
@Integer[2],
@Integer[2],
@Integer[2],
@Integer[2],
@Integer[2],
@Integer[5],
@Integer[109],
]

4.退出arthas

如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。

如果想完全退出arthas,可以执行shutdown命令。

附录:

Arthas 用户文档https://alibaba.github.io/arthas/quick-start.html

Arthas github地址: https://github.com/alibaba/arthas

上一篇:原生JavaScript事件详解


下一篇:java 20 - 6 加入了异常处理的字节输出流的操作