您好,登錄后才能下訂單哦!
Arthas中如何使用watch命令,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
Arthas 官網是這么介紹自己的:
Arthas 是 Alibaba 開源的 Java 診斷工具,深受開發者喜愛。 當你遇到以下類似問題而束手無策時,Arthas 可以幫助你解決:
這個類從哪個 jar 包加載的?為什么會報各種類相關的 Exception?
我改的代碼為什么沒有執行到?難道是我沒 commit?分支搞錯了?
遇到問題無法在線上 debug,難道只能通過加日志再重新發布嗎?
線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!
是否有一個全局視角來查看系統的運行狀況?
有什么辦法可以監控到 JVM 的實時運行狀態?
怎么快速定位應用的熱點,生成火焰圖?
方式一:通過 Cloud Toolkit 實現 Arthas 一鍵遠程診斷
Cloud Toolkit 是阿里云發布的免費本地 IDE 插件,幫助開發者更高效地開發、測試、診斷并部署應用。通過插件,可以將本地應用一鍵部署到任意服務器,甚至云端(ECS、EDAS、ACK、ACR 和 小程序云等);并且還內置了 Arthas 診斷、Dubbo工具、Terminal 終端、文件上傳、函數計算 和 MySQL 執行器等工具。不僅僅有 IntelliJ IDEA 主流版本,還有 Eclipse、Pycharm、Maven 等其他版本。
推薦使用 IDEA 插件下載 Cloud Toolkit 來使用 Arthas:http://t.tb.cn/2A5CbHWveOXzI7sFakaCw8
方式二:直接下載
地址:https://github.com/alibaba/arthas。
curl -O https://alibaba.github.io/arthas/arthas-boot.jar && java -Dfile.encoding=UTF-8 -jar arthas-boot.jar 復制代碼
稍微解釋一下上面這條 shell 命令。命令分為兩部分,&&
之前的部分是下載 Arthas,之后的部分是啟動 Arthas。
你可能會疑惑下載文件為什么不用 wget
而是用 curl
?這是因為有些服務器是沒有預裝 wget
的,但是基本都預裝了 curl
。如果你的服務器預裝了 wget
的話完全可以把 'curl' 改成 wget
。
如果使用 wget 的話命令可以改成:
# wget 版命令 wget https://alibaba.github.io/arthas/arthas-boot.jar && java -Dfile.encoding=UTF-8 -jar arthas-boot.jar 復制代碼
另外一個需要解釋的點是 -Dfile.encoding=UTF-8
,這個 Java 設置是為了讓 Arthas 輸出中文的時候不會亂碼,這一點可以看一下我以前的文章 由 Arthas 中文亂碼引發的 Java 默認編碼思考。
watch
讓你能方便地觀察到指定方法的調用情況。能觀察到的范圍為:返回值
、拋出異常
、入參
(還能觀察執行函數的對象本身,不知道為什么官方介紹的時候沒說這個」,通過編寫 OGNL 表達式進行對應變量的查看。
# watch -h # USAGE watch [-b] [-e] [-x <value>] [-f] [-h] [-n <value>] [-E] [-M <value>] [-s] class-pattern method-pattern express [condition-express] 復制代碼
returnObj
使用方式看著復雜,其實很簡單。來個最簡單的示例: 假設我們要觀察下面這段代碼中字符串的 contains
方法。
public class App { public static void main(String[] args) throws IOException { String hello = "Hello Arthas"; while (true) { boolean contains = StringUtils.contains(hello, "Arthas"); System.out.println(contains); } } } 復制代碼
可以使用如下語句:
## 觀察 contains 返回結果 [arthas@11939]$ watch org.apache.commons.lang3.StringUtils contains returnObj -n 3 # Press Q or Ctrl+C to abort. # Affect(class-cnt:1 , method-cnt:2) cost in 68 ms. # ts=2020-05-02 16:46:04; [cost=2.424254ms] result=@Boolean[true] # ts=2020-05-02 16:46:05; [cost=0.21033ms] result=@Boolean[true] # ts=2020-05-02 16:46:06; [cost=0.165514ms] result=@Boolean[true] 復制代碼
-n 3
表示只執行三次,這參數挺常用,不然很容易被輸出刷屏。
condition-express
顯然,真實的案例肯定不會如上面的示例那么簡單。 真實的服務代碼中,肯定不止一個地方調用了 String 的 contains
方法。我們需要把無關的調用過濾掉。
## 觀察 contains 返回結果,并且過濾掉無關調用 [arthas@11939]$ watch org.apache.commons.lang3.StringUtils contains returnObj 'params[1]=="Arthas"' # Press Q or Ctrl+C to abort. # Affect(class-cnt:1 , method-cnt:2) cost in 29 ms. # ts=2020-05-02 16:48:50; [cost=0.331109ms] result=@Boolean[true] # ts=2020-05-02 16:48:51; [cost=0.175224ms] result=@Boolean[true] # ts=2020-05-02 16:48:52; [cost=0.138984ms] result=@Boolean[true] 復制代碼
入參是一個很容易把不同調用區分開的方法,通過 params[1]=="Arthas"
這個 condition-express
,我們可以只保留第二個入參是 Arthas
的函數調用。
[arthas@11939]$ watch org.apache.commons.lang3.StringUtils contains {params,returnObj} 'params[1]=="Arthas"' # Press Q or Ctrl+C to abort. # Affect(class-cnt:1 , method-cnt:2) cost in 33 ms. # ts=2020-05-02 16:51:27; [cost=0.507486ms] result=@ArrayList[ # @Object[][isEmpty=false;size=2], # @Boolean[true], # ] 復制代碼
通過 {}
把字段包起來,可以同時觀察想觀察的字段。可以注意到一個點,params
是一個數組,但是打印 params
的時候并沒有把具體內容打印出來,這個時候可以使用 -x 2
來指定打印對象的屬性遍歷深度。
arthas@11939]$ watch org.apache.commons.lang3.StringUtils contains {params,returnObj} 'params[1]=="Arthas"' -x 2 # Press Q or Ctrl+C to abort. # Affect(class-cnt:1 , method-cnt:2) cost in 35 ms. # ts=2020-05-02 16:51:33; [cost=0.391218ms] result=@ArrayList[ # @Object[][ # @String[Hello Arthas], # @String[Arthas], # ], # @Boolean[true], # ] 復制代碼
在陌陌做動態推薦開發的時候,測試時經常會遇到查看某個用戶是否開啟了相應的業務開關,經常就會需要查看某個實驗開關是否開啟。
## 查看陌陌用戶 1234567 是否開啟 ElasticSearch 開關 watch com.momo.Experiment enableElasticSearch returnObj 'target.momoId=="1234567"' # ts=2020-05-02 20:09:46; [cost=24.443527ms] result=@Boolean[true] 復制代碼
我還經常會根據入參的陌陌用戶 id 進行判斷,查看返回結果或者異常:
## 查看 MorecControlFlow 類的 process 方法返回結果 ## process 方法第一個參數的 momoId 屬性值為 “123454567” 才生效 ## 類路徑和陌陌號都非真實數據 watch com.momo.MorecControlFlow process returnObj 'params[0].momoId=="123454567"' # ts=2019-03-18 21:09:46; [cost=264.434972ms] result=@Boolean[true] ## 查看 IMorecShuffler 類的 shuffle 拋的異常 ## process 方法第一個參數的 momoId 屬性值為 “123454567” 才生效 watch com.momo.plugins.shuffler.IMorecShuffler shuffle throwExp 'params[0].morecRequest.momoId=="123454567"' # ts=2019-03-27 20:54:29; [cost=46.642339ms] result=java.lang.IndexOutOfBoundsException: Index: 12, Size: 11 at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:665) at java.util.ArrayList.add(ArrayList.java:477) at com.momo.plugin.shuffler.RoomShuffler.shuffle(RoomShuffler:45)
看完上述內容,你們掌握Arthas中如何使用watch命令的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。