安裝
安裝很容易 , arthas
是以 jar 包的形式運行的
wget https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
模擬
我們以官方提供的例子為例
wget https://arthas.aliyun.com/math-game.jar
java -jar math-game.jar
然后再另外的窗口運行 arthas
, 下面使用 monitor
命令, 該命令可以監控方法調用的情況包括 :
例如我們可以知道知道每5秒, run
方法的調用情況.
[arthas@38487]$ monitor demo.run -c 5
The argument 'method-pattern' is required, description: Method of Pattern Matching
[arthas@38487]$ monitor demo.MathGame run -c 5
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 20 ms, listenerId: 2
timestamp class method total success fail avg-rt(ms fail-rate
)
------------------------------------------------------------------------------------------------------------------------------------------------------
2021-06-13 21:58:31 demo.MathGame run 4 4 0 0.15 0.00%
timestamp class method total success fail avg-rt(ms fail-rate
)
------------------------------------------------------------------------------------------------------------------------------------------------------
2021-06-13 21:58:36 demo.MathGame run 5 5 0 0.13 0.00%
timestamp class method total success fail avg-rt(ms fail-rate
)
可以看到 avg-rt(平均響應) 我們可以找到最耗時的方法 , 然后進行定位問題 , 這里我們以下面這篇文章為例子 , 定位 druid 的一個問題 ,
可以看到作者找到了比較耗時的方法調用, 於是作者使用了 trace
命令進行查看,而該方法是調用了 java
本身庫內的方法 為了定位問題, 作者 monitor
了 ReentrantLock
這個方法
最終定位到了問題 , 而為了查看某個線程阻塞的原因, 我們對線程進行了查看, 找到某些阻塞的線程
thread --state BLOCKING
最后看到
java.util.concurrent.locks.ReentrantLock$FairSync@60190bc0
at sun.misc.Unsafe.park(Native Method)
- waiting on java.util.concurrent.locks.ReentrantLock$FairSync@60190bc0
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:224)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at com.alibaba.druid.pool.DruidDataSource.recycle(DruidDataSource.java:1913)
at com.alibaba.druid.pool.DruidPooledConnection.recycle(DruidPooledConnection.java:324)
at com.alibaba.druid.pool.DruidPooledConnection.syncClose(DruidPooledConnection.java:300)
at com.alibaba.druid.pool.DruidPooledConnection.close(DruidPooledConnection.java:255)
at org.springframework.jdbc.datasource.DataSourceUtils.doCloseConnection(DataSourceUtils.java:341)
原來是使用了公平鎖導致的,找到了問題就可以進行優化了.
trace 命令
trace
命令是為了方法內部調用路徑,並輸出方法路徑上的每個節點上耗時 , 上面的例子有一個就是調用了 trace
的效果
tread 命令
這個命令就比較常用點,用戶查找阻塞的線程等等
例如可以這樣使用
[arthas@38487]$ thread -n 5
"C2 CompilerThread2" [Internal] cpuUsage=2.84% deltaTime=5ms time=549ms
"C1 CompilerThread3" [Internal] cpuUsage=0.26% deltaTime=0ms time=772ms
"arthas-command-execute" Id=23 cpuUsage=0.12% deltaTime=0ms time=316ms RUNNABLE
at sun.management.ThreadImpl.dumpThreads0(Native Method)
at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:448)
at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:206)
at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:122)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"C2 CompilerThread0" [Internal] cpuUsage=0.06% deltaTime=0ms time=518ms
"VM Periodic Task Thread" [Internal] cpuUsage=0.03% deltaTime=0ms time=1348ms
[arthas@38487]$ thread --all
Threads Total: 30, NEW: 0, RUNNABLE: 8, BLOCKED: 0, WAITING: 4, TIMED_WAITING: 3, TERMINATED: 0, Internal threads: 15
ID NAME GROUP PRIORITY STATE %CPU DELTA_TIME TIME INTERRUPTED DAEMON
-1 C1 CompilerThread3 - -1 - 0.32 0.000 0:0.781 false true
23 arthas-command-execute system 5 RUNNABLE 0.09 0.000 0:0.318 false true
-1 VM Periodic Task Thread - -1 - 0.05 0.000 0:1.355 false true
-1 VM Thread - -1 - 0.04 0.000 0:0.168 false true
2 Reference Handler system 10 WAITING 0.0 0.000 0:0.003 false true
3 Finalizer system 8 WAITING 0.0 0.000 0:0.005 false true
4 Signal Dispatcher system 9 RUNNABLE 0.0 0.000 0:0.000 false true
10 Attach Listener system 9 RUNNABLE 0.0 0.000 0:0.012 false true
12 arthas-timer system 9 WAITING 0.0 0.000 0:0.000 false true
15 arthas-NettyHttpTelnetBootstrap-3-1 system 5 RUNNABLE 0.0 0.000 0:0.017 false true
16 arthas-NettyWebsocketTtyBootstrap-4-1 system 5 RUNNABLE 0.0 0.000 0:0.002 false true
17 arthas-NettyWebsocketTtyBootstrap-4-2 system 5 RUNNABLE 0.0 0.000 0:0.001 false true
18 arthas-shell-server system 9 TIMED_WAITIN 0.0 0.000 0:0.007 false true
19 arthas-session-manager system 9 TIMED_WAITIN 0.0 0.000 0:0.002 false true
20 arthas-UserStat system 9 WAITING 0.0 0.000 0:0.000 false true
22 arthas-NettyHttpTelnetBootstrap-3-2 system 5 RUNNABLE 0.0 0.000 0:0.243 false true
25 arthas-NettyHttpTelnetBootstrap-3-3 system 5 RUNNABLE 0.0 0.000 0:0.101 false true
1 main main 5 TIMED_WAITIN 0.0 0.000 0:0.543 false false
-1 C2 CompilerThread2 - -1 - 0.0 0.000 0:0.549 false true
-1 GC task thread#7 (ParallelGC) - -1 - 0.0 0.000 0:0.042 false true
-1 GC task thread#6 (ParallelGC) - -1 - 0.0 0.000 0:0.046 false true
-1 GC task thread#0 (ParallelGC) - -1 - 0.0 0.000 0:0.045 false true
-1 C2 CompilerThread0 - -1 - 0.0 0.000 0:0.518 false true
-1 Service Thread - -1 - 0.0 0.000 0:0.000 false true
-1 C2 CompilerThread1 - -1 - 0.0 0.000 0:0.526 false true
-1 GC task thread#1 (ParallelGC) - -1 - 0.0 0.000 0:0.038 false true
-1 GC task thread#2 (ParallelGC) - -1 - 0.0 0.000 0:0.046 false true
-1 GC task thread#3 (ParallelGC) - -1 - 0.0 0.000 0:0.033 false true
-1 GC task thread#5 (ParallelGC) - -1 - 0.0 0.000 0:0.044 false true
-1 GC task thread#4 (ParallelGC) - -1 - 0.0 0.000 0:0.051 false true
[arthas@38487]$ 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)
[arthas@38487]$ thread --state RUNNABLE
Threads Total: 15, NEW: 0, RUNNABLE: 8, BLOCKED: 0, WAITING: 4, TIMED_WAITING: 3, TERMINATED: 0
ID NAME GROUP PRIORITY STATE %CPU DELTA_TIME TIME INTERRUPTED DAEMON
23 arthas-command-execute system 5 RUNNABLE 0.05 0.000 0:0.324 false true
4 Signal Dispatcher system 9 RUNNABLE 0.0 0.000 0:0.000 false true
10 Attach Listener system 9 RUNNABLE 0.0 0.000 0:0.012 false true
15 arthas-NettyHttpTelnetBootstrap-3-1 system 5 RUNNABLE 0.0 0.000 0:0.017 false true
16 arthas-NettyWebsocketTtyBootstrap-4-1 system 5 RUNNABLE 0.0 0.000 0:0.002 false true
17 arthas-NettyWebsocketTtyBootstrap-4-2 system 5 RUNNABLE 0.0 0.000 0:0.001 false true
22 arthas-NettyHttpTelnetBootstrap-3-2 system 5 RUNNABLE 0.0 0.000 0:0.243 false true
25 arthas-NettyHttpTelnetBootstrap-3-3 system 5 RUNNABLE 0.0 0.000 0:0.117 false true
[arthas@38487]$
參考資料
- https://arthas.aliyun.com/doc/index.html (重要,文檔,推薦一看)