Arthas監控學習與分享

Arthas

概述

Arthas 阿里巴巴最近開源出來的一個針對 java 的工具,主要是針對 java 的問題進行診斷。

  1. 這個工具可以協助你做下面這些事情:
  2. 這個類是從哪個 jar 包加載而來的?
  3. 爲什麼會報各種類相關的 Exception?
  4. 線上遇到問題無法 debug,難道只能反覆通過增加日誌再重新發布嗎?
  5. 線上的代碼爲什麼沒有執行到這裏?是由於代碼沒有 commit?還是搞錯了分支?
  6. 線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現。
  7. 是否有一個全局視角來查看系統的運行狀況?
  8. 有什麼辦法可以監控到JVM的實時運行狀態?

 

本文檔目前僅用於windows環境。

參考:https://alibaba.github.io/arthas/

下載安裝:

https://www.jianshu.com/p/c2d19e4470b6  參考

1.下載地址:

http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22

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

  1. 編譯修改好的文件,用指定classloader

mc -c 10fe49d6 tmp/TcslCollectionUtil.java -d tmp

如果用jad反編譯的文件修改完在編譯.class文件總有問題,一但複雜的文件就會各種報錯,缺少符號,jar找不到之類的。有說是jad流程有BUG的:

  1. 執行熱部署

使用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

可能有多個,你需要選擇需要監控的。

啓動成功如下:

  1. 外部訪問

另一臺機器也需要啓動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的狀況

 

發佈了7 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章