Arthas
概述
Arthas 是 阿里巴巴最近開源出來的一個針對 java 的工具,主要是針對 java 的問題進行診斷。
- 這個工具可以協助你做下面這些事情:
- 這個類是從哪個 jar 包加載而來的?
- 爲什麼會報各種類相關的 Exception?
- 線上遇到問題無法 debug,難道只能反覆通過增加日誌再重新發布嗎?
- 線上的代碼爲什麼沒有執行到這裏?是由於代碼沒有 commit?還是搞錯了分支?
- 線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現。
- 是否有一個全局視角來查看系統的運行狀況?
- 有什麼辦法可以監控到JVM的實時運行狀態?
本文檔目前僅用於windows環境。
參考:https://alibaba.github.io/arthas/
下載安裝:
https://www.jianshu.com/p/c2d19e4470b6 參考
1.下載地址:
2.下載bin包並解壓:
使用:
簡單使用:
首先,啓動你的tomcat的項目。
打開cmd查看你的tomcat的pid:netstat -ano|findstr 7004
拿到PID以後,切換到Arthas的路徑下執行as.bat PID
啓動arthas服務,會佔用3658 8563 兩個端口;已經佔用的需要提前釋放;然後會彈出一個監控頁面。此時執行:dashboard
會出現:整個進程的情況
Ctrl+C也能退出實時刷新。
help——查看命令幫助信息
cat——打印文件內容,和linux裏的cat命令類似
pwd——返回當前的工作目錄,和linux命令類似
cls——清空當前屏幕區域
session——查看當前會話的信息
reset——重置增強類,將被 Arthas 增強過的類全部還原,Arthas 服務端關閉時會重置所有增強過的類
version——輸出當前目標 Java 進程所加載的 Arthas 版本號
history——打印命令歷史
quit——退出當前 Arthas 客戶端,其他 Arthas 客戶端不受影響
shutdown——關閉 Arthas 服務端,所有 Arthas 客戶端全部退出
keymap——Arthas快捷鍵列表及自定義快捷鍵
監控命令:
1.monitor: 方法執行監控
monitor 命令是一個非實時返回命令。
實時返回命令是輸入之後立即返回,而非實時返回的命令,則是不斷的等待目標 Java 進程返回信息,直到用戶輸入 Ctrl+C 爲止。
案例1
每5秒進行檢查一次,檢查5秒內產生的訪問
2.watch: 方法執行數據觀測
特別說明:
- watch 命令定義了4個觀察事件點,即 -b 方法調用前,-e 方法異常後,-s 方法返回後,-f 方法結束後
- 4個觀察事件點 -b、-e、-s 默認關閉,-f 默認打開,當指定觀察點被打開後,在相應事件點會對觀察表達式進行求值並輸出
- 這裏要注意方法入參和方法出參的區別,有可能在中間被修改導致前後不一致,除了 -b 事件點 params 代表方法入參外,其餘事件都代表方法出參
- 當使用 -b 時,由於觀察事件點是在方法調用前,此時返回值或異常均不存在
案例1
注:如果需要查看詳細的返回值信息,可以設置-x 3增加屬性遍歷深度默認值爲1。
案例2
注:發現入參數量爲0,但實際加單是有傳遞參數的。原因是因爲addOrder()方法沒有參數。
案例3
案例4
3.tt: 記錄下指定方法每次調用的入參和返回信息,並能對這些不同的時間下調用進行觀測。
watch 雖然很方便和靈活,但需要提前想清楚觀察表達式的拼寫,這對排查問題而言要求太高,因爲很多時候我們並不清楚問題出自於何方,只能靠蛛絲馬跡進行猜測。
這個時候如果能記錄下當時方法調用的所有入參和返回值、拋出的異常會對整個問題的思考與判斷非常有幫助。
4.options: 全局開關
打開執行結果存日誌功能:options save-result true
注:也可以執行以下命令,後臺運行內容保存到指定文件
5.getstatic
通過getstatic命令可以方便的查看類的靜態屬性。使用方法爲getstatic
class_name
field_name
如果該靜態屬性是一個複雜對象,還可以支持在該屬性上通過ognl表示進行遍歷,過濾,訪問對象的內部屬性等操作。
性能相關的命令
Stack-輸出當前方法被調用的調用路徑
stack cn.com.tcsl.canyin.pos.reception.controller.ReceptionBusinessController incrPointList
Jad-反編譯class
jad cn.com.tcsl.canyin.pos.reception.controller.ReceptionBusinessController incrPointList
Trace-命令能主動搜索 class-pattern/method-pattern 對應的方法調用路徑,渲染和統計整個調用鏈路上的所有性能開銷和追蹤調用鏈路。
[arthas@5044]$ trace cn.com.tcsl.canyin.wuu.service.local.CrmService getCrmCardMessage
[arthas@5044]$ trace -j cn.com.tcsl.canyin.wuu.service.local.CrmService getCrmCardMessage
過濾 java的自帶函數
[arthas@5044]$ trace -j cn.com.tcsl.canyin.pos.controller.AddOrderController addOrder 'cost>10'
過濾處理時間超過10ms的請求(整個方法超過10ms)
這裏存在一個統計不準確的問題,就是所有方法耗時加起來可能會小於該監測方法的總耗時,這個是由於 Arthas 本身的邏輯會有一定的耗時
Jvm-查看當前 JVM 的信息
Thread-查看當前 JVM 的線程堆棧信息
Thread PID 查看指定線程詳細信息
Thread –n 3 輸出最忙的N的線程
Thread –b 找出阻塞其它線程的線程
Sysprop-可以打印所有的System Properties信息
[arthas@5044]$ sysprop file.encoding 查看單key
sysprop file.encoding UTF-8 修改配置
Sysenv-命令可以獲取到環境變量,比如ssh登錄的ip等
其他常用指令
Sc-打印api包下所有的類
sc cn.com.tcsl.canyin.pos.*
搜索接口實現類
sc javax.servlet.Filter
查看詳細信息
sc -d javax.servlet.Filter
Sm-打印類的詳細信息
[arthas@5044]$ sm -d cn.com.tcsl.canyin.pos.controller.AddOrderController
打印指定方法的詳細信息
sm -d cn.com.tcsl.canyin.pos.controller.AddOrderController addOrder
Ognl-可以動態執行代碼
Ognl ognl '@[email protected]("hello ognl")'
Dump- 類似jmap命令的heap dump功能
熱部署
jad/mc/redefine線上熱更新一條龍
1.將反編譯的文件保存到一個指定路徑
[arthas@11404]$ jad --source-only cn.com.tcsl.canyin.pos.controller.AddOrderController > tmp/AddOrderController.java
這個路徑在你的tomcat下。。。。。
2.找到文件對應JVM的classloader
sc -d *AddOrderController | grep classLoaderHash
- 編譯修改好的文件,用指定classloader
mc -c 10fe49d6 tmp/TcslCollectionUtil.java -d tmp
如果用jad反編譯的文件修改完在編譯.class文件總有問題,一但複雜的文件就會各種報錯,缺少符號,jar找不到之類的。有說是jad流程有BUG的:
- 執行熱部署
使用mc編譯後的文件
redefine S:/work/Tomcat/bin/tmp/cn/com/tcsl/framework/common/util/TcslCollectionUtil.class
直接使用編譯後文件執行熱部署
替換文件的反編譯如下:
本地代碼如下:
[arthas@3300]$ redefine tmp/AddOrderController.class tmp/BizAddOrder.class
熱部署不支持新增類和方法,也就是隻能update現有的代碼。
正在跑的函數,沒有退出不能生效。
使用想法:
可以靠java啓動。
首先在目前已存在的Listener就夠用實在不行就實現HttpServlet走init;方法中調用Process p = Runtime.getRuntime().exec(cmd);
cmd既是查詢pid和執行as.bat pid。
遠程監控:
參考:https://blog.csdn.net/lang_programmer/article/details/84726303
https://www.cnblogs.com/theRhyme/p/10659265.html
1.被調用端啓動Arthas需要使用命令:
java -jar arthas-boot.jar --target-ip 192.168.9.165
--target-ip即監聽的端口對外暴露,外部訪問使用,你監聽IP即可。
2.執行完它會讓你選去監聽那個PID
可能有多個,你需要選擇需要監控的。
啓動成功如下:
- 外部訪問
另一臺機器也需要啓動arthas服務並在web頁面輸入ip即可監控到
另外退出時一定要shutdowm你的arthas服務,不然下次啓動報錯
Linux上監控
1.首先 curl -L https://alibaba.github.io/arthas/install.sh | sh(下載)
2. ./as.sh(啓動)
3.執行完第三行命令後arthas 會自動查找 可以attach的pid 供你選擇,然後你選擇其前面的數字
4.然後執行dashboard 可以顯示該jvm的狀況