Java診斷工具Arthas
1. Arthas簡介
Arthas是阿里開源的一個線上java診斷工具,發現阿里還是挺喜歡開源一些技術的,造福人類。昨天試用了一下,發現真是強大,解決了我工作兩年的很多困擾,有點相見恨晚的感覺。
根據官網的說明,它能解決下面的問題:
當你遇到以下類似問題而束手無策時,
Arthas
可以幫助你解決:
- 這個類從哪個 jar 包加載的?為什么會報各種類相關的 Exception?
- 我改的代碼為什么沒有執行到?難道是我沒 commit?分支搞錯了?
- 遇到問題無法在線上 debug,難道只能通過加日志再重新發布嗎?
- 線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!
- 是否有一個全局視角來查看系統的運行狀況?
- 有什么辦法可以監控到JVM的實時運行狀態?
Arthas
采用命令行交互模式,同時提供豐富的Tab
自動補全功能,進一步方便進行問題的定位和診斷。
2. Arthas安裝
在Linux下直接執行curl -L https://alibaba.github.io/arthas/install.sh | sh
,然后執行./as.sh
就可以進入到Arthas的命令行界面。
3. Arthas試用
安裝完后試用了它的監控相關的功能,以后調試就不那么麻煩了。
# 進入命令行界面,剛進入的時候會顯示所有的java進程,選擇對應的數字然后回車就可以進入到對應的進程中
./as.sh
Arthas script version: 3.0.4.1
Found existing java process, please choose one and hit RETURN.
[1]: 27073 org.apache.rocketmq.namesrv.NamesrvStartup
* [2]: 2379 org.apache.catalina.startup.Bootstrap
2
Calculating attach execution time...
Attaching to 2379 using version 3.0.5...
real 0m0.249s
user 0m0.208s
sys 0m0.025s
Attach success.
telnet connecting to arthas server... current timestamp is 1545738424
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki: https://alibaba.github.io/arthas
version: 3.0.4
pid: 2379
timestamp: 1545738424462
$
3.1 monitor命令
monitor可以對某個類的某個方法進行周期性監控,來輸出方法的平均響應時間,成功失敗次數,調用次數等。
# 每3秒統計queryCatalog方法的調用次數,成功失敗次數和平均響應時間等。
$ monitor -c 3 com.timeline.services.CatalogService queryCatalog
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 82 ms.
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------------------------------
2018-12-25 19:57:41 com.timeline.services.CatalogService queryCatalog 3 3 0 2.46 0.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------------------------------
2018-12-25 19:57:44 com.timeline.services.CatalogService queryCatalog 0 0 0 0.00 0.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------------------------------
2018-12-25 19:57:47 com.timeline.services.CatalogService queryCatalog 0 0 0 0.00 0.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------------------------------
2018-12-25 19:57:50 com.timeline.services.CatalogService queryCatalog 2 2 0 2.08 0.00%
具體使用請見:https://alibaba.github.io/arthas/monitor.html。
3.2 watch命令
watch可以監控某個方法的出入參,異常信息等。
# 觀察方法的出入參
# -x表示遍歷深度,可以調整來打印具體的參數和結果內容,默認值是1。
$watch com.timeline.services.CatalogService queryCatalog "{params,returnObj}" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 73 ms.
ts=2018-12-25 19:49:55;result=@ArrayList[
@Object[][isEmpty=true;size=0],
@ArrayList[
@CatalogVO[CatalogVO(id=59, name=wangjun, location=beijing, time=1537256454000, description=desccc)],
],
]
# 可以看到入參是空的,出參是一個list
具體使用請見:https://alibaba.github.io/arthas/watch.html。
3.3 trace命令
trace可以輸出方法內部調用關系,並打印方法內部每個調用的耗時。
# 打印queryCatalog方法內每個調用的耗時
$ trace com.timeline.services.CatalogService queryCatalog
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 101 ms.
`---ts=2018-12-25 20:00:25;thread_name=http-nio-8080-exec-8;id=1b;is_daemon=true;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@4d1110a3
`---[2.896979ms] com.timeline.services.CatalogService:queryCatalog()
+---[2.605774ms] com.timeline.dao.CatalogDao:queryCatalog()
+---[0.0048ms] java.util.ArrayList:<init>()
+---[min=0.001154ms,max=0.00634ms,total=0.007494ms,count=2] java.util.List:size()
+---[0.004428ms] java.util.List:get()
+---[0.005115ms] com.timeline.entity.Catalog:getId()
+---[0.003107ms] com.timeline.entity.Catalog:getName()
+---[0.0026ms] com.timeline.entity.Catalog:getLocation()
+---[0.002573ms] com.timeline.entity.Catalog:getTime()
+---[0.005901ms] com.timeline.common.Utils:timestamp2Long()
+---[0.002543ms] com.timeline.entity.Catalog:getDescription()
+---[0.005133ms] com.timeline.vo.CatalogVO:<init>()
`---[0.004174ms] java.util.List:add()
具體使用請見:https://alibaba.github.io/arthas/trace.html。
3.4 stack命令
stack可以輸出方法的整個調用路徑。
# 打印queryCatalog方法的整個調用路徑(不拋出堆棧也能看到調用鏈啦!)
$ stack com.timeline.services.CatalogService queryCatalog
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 82 ms.
ts=2018-12-25 20:02:56;thread_name=http-nio-8080-exec-9;id=1c;is_daemon=true;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@4d1110a3
@com.timeline.controllers.CalalogController.queryCatalog()
at sun.reflect.GeneratedMethodAccessor46.invoke(null:-1)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
具體使用請見:https://alibaba.github.io/arthas/stack.html。
3.5 tt命令
記錄方法每次的調用出入參和異常信息,並且完整保留調用現場,可以再次模擬調用。
# 記錄每次調用queryCatalog的情況,可以根據其他命令打印出入餐和復現現場
$ tt -t com.timeline.services.CatalogService queryCatalog
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 128 ms.
INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1008 2018-12-25 20:04:46 4.747987 true false 0x2577a8a4 CatalogService queryCatalog
1009 2018-12-25 20:04:47 2.270835 true false 0x2577a8a4 CatalogService queryCatalog
1010 2018-12-25 20:04:47 1.434482 true false 0x2577a8a4 CatalogService queryCatalog
1011 2018-12-25 20:04:48 1.82891 true false 0x2577a8a4 CatalogService queryCatalog
1012 2018-12-25 20:04:49 2.27361 true false 0x2577a8a4 CatalogService queryCatalog
具體使用請見:https://alibaba.github.io/arthas/tt.html。
當然除此之外還有很豐富的其他功能,比如JVM,ClassLoader相關的命令。