前言
作為一名資深後端開發,你在生産環境一定會碰到這樣的場景:
産品:線上這個頁面加載比較慢,前端同學說是接口響應比較慢,你能幫忙優化下嗎?
後端:不應該啊,測試環境很絲滑啊。
産品:要不你自己操作試下?
經過實操,線上環境果然一直轉圈圈,然後你轉眼看上那座山,看着那些拉幾屏棧幀還沒結束的函數,各種方法調用,嵌套,然後你那充滿智慧的小腦袋瓜立馬想到從日志上看出端倪,但是那少的可憐的日志反手給了你潑了一盆冷水。
方法調用鍊路繁雜,調用耗時在日志中缺失,目前能想到的最好的辦法就是拉分支→加上耗時→上線→找到耗時最久的代碼→拉分支→優化代碼→上線。相信這是很多同學的處理方式,這個過程雖然思路清晰,但是很繁瑣。
那如果有這樣一個工具,隻需簡單的指令,就能線上給你列出所有調用鍊路耗時,那爽不爽,絲滑不絲滑,那我們就一起來了解下這個颠覆問題排查方式的工具,它就是Arthas。
Arthas介紹
- 2.1 Arthas是什麼?
Arthas是由阿裡開源的一款線上監控診斷産品,遵循Apache License 2.0開源協定。
- 2.2 Arthas能做什麼?
- 無需修改代碼線上監測代碼耗時。
- 無需修改代碼線上抓取方法入參出參。
- 線上反編譯位元組碼檔案。
- 生成火焰圖查找引起FULLGC的大對象。
- 以及其他你能想到或想不到的功能,快來一起發掘吧……
Arthas實戰
- 3.1 環境準備
- 3.1.1 編寫測試工程:https://github.com/NotExistUserName/test-project.git,主要示範代碼如下:
Arthas示範代碼
測試工程啟動
- 3.1.3 執行 curl -O https://arthas.aliyun.com/arthas-boot.jar 下載下傳arthas。
上傳測試jar,并下載下傳Arthas
- 3.1.4 執行 java -jar arthas-boot.jar 運作Arthas,會得到如下資訊:
Arthas運作後截圖
- 3.1.5 輸入1,進行Arthas控制台如下:
PS:特别注意我們這裡是輸入1按回車,而不是輸入7345,Arthas也有資訊提示。
Arthas控制台
- 3.2 常用功能實戰
- 3.2.1 線上抓取入參出參
我們假設測試工程中的方法com.github.controller.UserController#getByUid已經上線,我們沒有列印出參入參,那麼此時Arthas就發揮大作用了,我們在控制台輸入如下指令并回車:
watch com.github.controller.UserController getByUid -x 2 -b -s
然後我們請求接口com.github.controller.UserController#getByUid,我們就可以清晰的看到接口的入參與出參:
watch指令執行截圖
指令的用法也很簡單,格式為:watch 全例名 方法名稱 ,後面則是預設參數:
-x:即指定Arthas展開入參和出參屬性的層級,最大支援到4,預設為1。-x 2就是将對象展開到第二層級。
-b:即在方法調用前輸出一次觀察表達式的結果。
-s:即在方法調用後輸出一次觀察表達式的結果。(預設開啟)
以上指令執行後,我們會發現Arthas抓取一次入參出參後并沒有退出,而是之後的每次請求都會抓取,那麼對于線上這麼大的并發量,Arthas這種通過Java agent挂載方式實作,每次請求都進行攔截輸出的話,那勢必會對線上性能造成損耗,是以Arthas也提前考慮到了這點,貼心的為我們提供了-n 參數,即如下指令:
watch com.github.controller.UserController getByUid -x 2 -b -s -n 1
使用-n參數指定觀察的次數
我們會發現加上-n 1之後,Arthas隻觀察了一次就自動退出了,這樣就很有中庸之道的意味了,既為我們排查問題提供了線索,又不會過于影響線上性能。
- 3.2.2 線上反編譯Java代碼
假如我們有一個需求提測了,但是現在測試提出一個與預期代碼完全不符的問題,就和沒有我們新增的那段代碼是一樣的效果,我們一般采用的方法就是将jar包從伺服器上下載下傳下來,然後用JD-GUI打開,看下伺服器上的代碼是否是最新的代碼。
那麼有了Arthas的加持,過程就會由繁轉簡,我們隻需要在Arthas控制台執行如下指令:
jad com.github.controller.UserController
Arthas反編譯代碼
Arthas就會将反編譯的結果絲滑的列印在控制台上,我們就能夠很直覺的看到我們的代碼是不是最新的,進而快速解決玄學問題,讓你徹底擺脫那句名言:不可能啊,我什麼都沒改啊?
當然如果你一個類中的方法很多的話,你如果隻想看某一個方法是不是最新的,你隻需要在以上指令後添加你需要反編譯的方法名稱即可,就像這樣:
jad com.github.controller.UserController getByUid
- 3.2.3 實時統計代碼耗時,線上分析代碼性能
就我個人而言,Arthas這個功能真的是王炸,很多時候,因為環境或者并發量等諸多原因,測試環境完全複現不了線上的性能問題,隻能按照文章開頭所描述的繁瑣工作進行排查,這一套繁瑣的流程下來,本來快速解決可以說是網絡抖動,硬被拖成了生産事故。年度3.25逃不掉了。
那Arthas是如何協助我們高效的排查性能問題的呢,我們隻要在控制台輸入如下指令
trace com.github.controller.UserController getByUid
我們就會得到這樣一張圖:
Arthas耗時截圖
我們可以很清晰的看到,getByUid這個方法的總耗時是:89.071157ms,調用棧中最耗時的方法是com.github.json.JsonUtils:silentString2Object,總共耗時:79.734267ms,占比89.52%,我們能夠很快的定位到性能慢的罪魁禍首是silentString2Object,那麼隻需要着重優化該方法即可優化線上性能問題。
結語
Arthas是一款功能非常強大且實用的工具,目前在阿裡也是大面積推廣,在日常工作中能夠快速定位疑難雜症,如果說Spring是後端的春天,那Arthas必須是夏天的脆甜冰西瓜。這樣一款良心工具各位同學愛了嗎。快去上手實踐吧。
分享一句非常喜歡的話:把根牢牢紮深,再等春風一來,便會春暖花開。
文章參考:
Arthas官網:https://arthas.aliyun.com/doc/quick-start.html
Arthas開源項目位址:https://github.com/alibaba/arthas
PS:以上引用資訊以及圖檔均來自網絡公開資訊,如有侵權,請留言或聯系
[email protected],立馬删除。