線上應用調試利器 --Arthas

  在以前的文章中,我介紹了使用 Btrace 工具進行線上代碼的debug (http://www.javashuo.com/article/p-ttklizae-gv.html),其大體原理就是經過字節碼注入的方式進行輔助排查。html

  能夠說,btrace 已經給咱們的開發調試一帶來了許多的方便,咱們在上面作任何想要的調試!可是,明顯, btrace 的使用仍是有必定成本的,好比:安裝應用,寫調試腳本...java

  因此,今天咱們再來看一大利器: arthas (阿爾薩斯)git

arthas 官網地址:https://alibaba.github.io/arthas/github

  arthas 的文檔真的寫得很是棒,能夠說一看就會。web

可是我仍是想寫一下一些本身的文檔,畢竟咱們每每只會用到其中皮毛功能而已。翻閱其全部文檔也仍是有點浪費了!spring

1、爲何要用 Arthas ?

  其實,這個問題在前面已回答,並且,你爲何要用 btrace ? 同理! 具體理由以下:服務器

  1. 能夠很方便查到一類是從哪一個 jar 包加載的?爲何會報各類類相關的 Exception?
  2. 懷疑本身的代碼未被部署到服務器,能夠經過命令快速驗證服務器上的代碼就是本地的代碼;
  3. 能夠直接經過 arthas 進行線上debug, 查看方法返回值以確認問題所在;
  4. 能夠很方便嵌入本身的debug代碼,快速驗證猜測;
  5. 操做完成後,能夠將全部debug代碼刪除,從而避免影響線上運行;

 

2、如何安裝?

  真的是超級簡單哦;1. 先把 arthas  的 工具jar包下載下來; 2. 運行便可;ide

wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar

   請問,還能更簡單嗎?工具

 

3、如何解決問題?

  通過上一步安裝,並運行以後,就差很少是圖形界面操做了。性能

  第一步,arthas 會檢測到目前正在有幾個運行中的java程序,你只需按照序號選擇就就能夠了。這裏你就徹底置身該應用環境了。接下來就能夠 do what ever you want to do 。

下面,我以幾個經常使用問題場景,來簡要看看其解決方案如何吧!

問題1. 我如何查找某個只知道大概的類,或者說我想確認某個類是否已被系統加載?

  經過這個問題,咱們能夠確認一點: 我寫的代碼是否被部署了。固然,若是是對於 war 包,其實這個問題比較容易解決,由於它是一個個的 class 文件,咱們能夠直接使用 find 命令查找便可。然而這畢竟只是理想,事實會很複雜!

  因此, arthas 怎麼查找一個類?

sc *DispatcharServlet      # 便可以找到須要的類全路徑,若是存在的話
sm org.springframework.web.servlet.DispatcherServlet getHandler # 查看某個方法的信息,若是存在的話 

  甚至咱們可使用通配符列出全部的方法:

 

問題2.  如何查看一個class類的具體信息?

  雖然經過上面檢查類和方法是否存在,可以解決一部分咱們排查代碼的問題,可是在咱們只是改動一個方法中的稍稍邏輯時,就沒法經過類和方法來確認問題,此時就須要進行反編譯後進行查看了!

  這事若是要我本身去幹,我多半隻是將jar包中的class文件,使用 javap 進行反編譯成可讀字節碼,而後很認真地核對類信息! javap 雖然已經在很大程度上減輕了咱們的閱讀壓力,但仍然門檻很高。

  而 使用 arthas 則簡單至極:

jad org.springframework.web.servlet.DispatcherServlet # 直接反編譯出java 源代碼,包含一此額外信息的

 

 

問題3. 如何跟蹤某個方法的返回值、入參.... ?

  這個問題實際上是咱們在用 btrace 這樣的工具的大部分時候的初衷!雖然 trace 腳本編寫並不複雜,可是千篇一概和頻繁地更改,也給咱們帶來了許多麻煩。

  而這在 arthas 就是一個命令的事!

watch com.test.ob testMethod "{params, returnObj, throwExp}" -e -x 2  # 同時監控入參,返回值,及異常

  若是有異常,直接打印出來,不然出入參直接監控,超級方便!

  這裏有支持複雜的 ognl 語法,實現更復雜邏輯,請參考: https://alibaba.github.io/arthas/watch.html

問題4. 查看最繁忙的線程,以及是否有阻塞狀況發生?

  查看繁忙的線程,通常咱們能夠經過 top 等系統命令進行查看,可是那畢竟要不少個步驟,很麻煩。

  而 arthas 則直觀明瞭:

thread -n 3 # 查看最繁忙的三個線程棧信息
thread  # 以直觀的方式展示全部的線程狀況
thread -b #找出當前阻塞其餘線程的線程

 

問題5. 如何驗證本身的代碼猜測,臨時更改代碼運行?

  可能我就是認爲其中有一個數字寫錯了,致使業務出錯,可是不太確認,因此想在線上直接驗證下!

  基本的經驗是,在本地改了代碼後,從新打包部署,而後重啓觀察效果。可是這太慢了!

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java  # 先反編譯出class源碼
 # 而後使用外部工具編輯內容
mc /tmp/UserController.java -d /tmp  # 再編譯成class
 # 最後,從新載入定義的類,就能夠實時驗證你的猜想了
redefine /tmp/com/example/demo/arthas/user/UserController.class

  如上,是直接更改線上代碼的方式,可是通常好像是編譯不成功的。因此,最好是 本地ide 編譯成 class 文件後,再上傳替換爲好!

  總之,已經徹底不用重啓和發佈了!這個功能真的很方便,比起重啓帶來的代價,真的是不可比的。好比,重啓時可能致使負載重分配,選主等等問題,就不是你能控制的了。

問題6. 我如何測試某個方法的性能問題?

  這個問題其實咱們通常不太關注,可是當性能成爲問題時,則真的要關注了!平時咱們使用 進入打印開始時間,退出打印一個結束時間這種方式,仍是有點low了!

monitor -c 5 demo.MathGame primeFactors

  以上命令直接統計 primeFactors 的響應問題:

  更多參考:https://alibaba.github.io/arthas/monitor.html

 

問題7. 更高級的追蹤工具!

  tt (TimeTumple) : 方法執行數據的時空隧道,記錄下指定方法每次調用的入參和返回信息,並能對這些不一樣的時間下調用進行觀測!

tt -t demo.MathGame primeFactors  # 追蹤方法的響應時間狀況

  trace: 輸出方法內部調用路徑,並輸出方法路徑上的每一個節點上耗時!

trace demo.MathGame run '#cost > 10' # 據調用耗時過濾

   

總之,你想要進行的調試,應該都能在這裏找到實現方案。去查看文檔便可!

  我以爲 arthas 有幾個很是好的理念: 1. 可視化追蹤,簡單易用; 2. 獨立classloader, 方便代碼卸載;3. 完善的文檔;

 

  其實,咱們排查問題時,老是費盡周折。然而當問題解決時,又發現簡單到不行。

阿里老話:結果很重要,過程也很重要!

相關文章
相關標籤/搜索