一次線上問題的綜合排查排查,兩個相同的系統的某個模塊,數據量更少的系統查詢更慢。
先說下總體思路:java
這樣看起來arthas真的很強大,它不只僅能處理上述問題,還能....mysql
Arthas 是Alibaba開源的Java診斷工具,採用命令行交互模式,提供了豐富的功能,是排查jvm相關問題的利器。
在逛github時,發現了這款利器,深刻了解以後,簡直驚爲天人。下面先列舉一下它能作的一些事情:git
進入當前系統的實時數據面板,按 ctrl+c 退出。這個面板會實時刷新,其中包括線程信息、內存信息、gc信息、還有一些運行時的數據。
另外,當運行在Ali-tomcat時,會顯示當前tomcat的實時信息,如HTTP請求的qps, rt, 錯誤數, 線程池信息等等。github
經過thread命令能夠查看當前jvm進程的線程詳情。能夠查看線程的cpu使用時間佔比,經過指定各類參數能夠找出最忙的幾個線程,以及阻塞其餘線程的線程。具體如何使用這裏很少作介紹,你們能夠去看arthas的官方文檔。正則表達式
當前最忙的前N個線程並打印堆棧 thread -i 5000 thread -i 5000
經過jvm命令直接輸出當前jvm的各類信息。算法
經過getstatic命令能夠方便的查看類的靜態屬性。sql
getstatic demo.MahtGame random
執行ognl表達式,可執行任意代碼express
Ognl @demo.MathGame@random
動態修改日誌級別apache
更詳細的介紹:https://github.com/alibaba/arthas/issues/11vim
將已加載類的字節碼dump到本地磁盤上。
有時咱們常常會不肯定線上或者測試環境的包是不是咱們修改過的,這時候就能夠經過jad反編譯來看下。
反編譯指定已加載類的源碼,jad demo.MathGame
將 JVM 中全部的classloader的信息統計出來,並能夠展現繼承樹,urls等。
該命令能夠加載外部的.class文件,而後覆蓋 jvm已加載的類。注意,這個命令不必定都能覆蓋成功,若是添加了新的field,就不會加載成功。
關於redefine,arthas的github上有個很是經典的userCase:
https://github.com/alibaba/arthas/issues/263
動態更新代碼,不用重啓jvm
參數名稱 | 參數說明 |
---|---|
class-pattern | 類名錶達式匹配 |
method-pattern | 方法名錶達式匹配 |
express | 觀察表達式 |
condition-express | 條件表達式 |
[b] | 在方法調用以前觀察 |
[e] | 在方法異常以後觀察 |
[s] | 在方法返回以後觀察 |
[f] | 在方法結束以後(正常返回和異常返回)觀察 |
[E] | 開啓正則表達式匹配,默認爲通配符匹配 |
[x:] | 指定輸出結果的屬性遍歷深度,默認爲 1 |
[n:] | 只執行n次,默認會不斷輸出,除非用戶按下cltr+c |
# 觀察CommonTest的test方法 # 輸出 入參、返回結果、拋出的異常 —— 輸出的內容能夠動態調整 # 後面跟着的是 條件表達式,表示耗時超過10ms才輸出 # -n 表示只執行一次,-x表示 入參和返回結果的展開層次爲5層 watch *.CommonTest test "{params,returnObj,throwExp}" '#cost>10' -x 5 -n 1 # 耗時大於10ms而且第一個參數等於1才輸出 watch *.CommonTest test "{params,returnObj,throwExp}" '#cost>10 && params[0]==1' -x 5 -n 1 # 第一個參數大於1 而且第二個參數等於hello才輸出 watch *.CommonTest test "{params,returnObj,throwExp}" 'params[0]>1 && params[1]=="hello"' -x 5 -n 1 # 第一個參數小於5或者第二個參數等於"world"就輸出 watch *.CommonTest test "{params,returnObj,throwExp}" 'params[0]<5 || params[1]=="wolrd"' -x 5 -n 1 # 第一個參數的name字段等於world時才輸出。 # 因爲在方法執行過程當中參數的name屬性可能發生改變,所以加上-b才能觀察到真正的入參 watch -b *.CommonTest test "{params,returnObj,throwExp}" 'params[0].name=="wolrd"' -x 5 -n 1 # 因爲同時指定了-s和-b,因此方法被調用一次,就會輸出2次結果(兩個場景分開輸出),分別是方法被調用前,和返回以後 # 注意,這裏若是-n只設置成1,那麼只會輸出-b對應的輸出,-s對應的輸出因爲沒有次數了就沒法輸出了 watch *.CommonTest test '{params,returnObj,throwExp}' -x 5 -n 2 -s -b
在填寫條件表達式時要注意一點,條件表達式中的params默認都是獲取的方法執行完後的參數信息,好比入參a的屬性name方法執行前是"hello",在方法執行後變成了"world",那麼條件表達式傳入'params[0].name="hello"'將不會輸出,只有填入'params[0].name="hello"'才能夠匹配上。這點對於後面的trace、stack命令也是同樣的。
查看方法輸入參數/返回值/異常信息,watch demo.MathGame primeFactors "{params,returnObj}" -x 2
monitor命令能夠監控方法的執行狀況。好比調用成功次數,失敗次數,失敗率、平均執行時間等等。默認120秒輸出一次,也就是說,當咱們輸入monitor命令以後,每120秒就會輸出一次統計結果。
經過-c參數能夠修改輸出頻率,支持通配符和正則表達式。
monitor -c 5 demo.MathGame primeFactors
方法內部調用路徑,並輸出方法路徑上的每一個節點上耗時,tt命令會記錄每次方法調用的各類信息。它和watch有些類似可是它能記錄下各個時間點的調用信息,以後隨時查看,甚至replay此次調用。
trace demo.MathGame run
timetunnel,記錄下指定方法每次調用的入參和返回信息,並能對這些不一樣的時間下調用進行觀測,同時可回放該方法調用
tt -t demo.MathGame primeFactors
直接重放請求參數
1.使用tt –t 類名次 方法名次 2.tt –play -i 1000
另外介紹幾個我常常用的工具,jmap,jstat,jstack,dump這些基本的就不介紹了。
TProfiler是一個能夠在生產環境長期使用的性能分析工具.它同時支持剖析和採樣兩種方式,記錄方法執行的時間和次數,生成方法熱點 對象建立熱點 線程狀態分析等數據,爲查找系統性能瓶頸提供數據支持.
TProfiler在JVM啓動時把時間採集程序注入到字節碼中,整個過程無需修改應用源碼.運行時會把數據寫到日誌文件,通常狀況下每小時輸出的日誌小於50M.
參考:https://blog.csdn.net/u013332124/article/details/84888074#11_redefine_157