Arthas使用

1.Arthas是什么

Arthas是Alibaba開源的Java診斷工具
他主要解決以下問(wèn)題

1.這個(gè)類從哪個(gè) jar 包加載的泳唠?為什么會(huì)報(bào)各種類相關(guān)的 Exception?
2.我改的代碼為什么沒(méi)有執(zhí)行到辆毡?難道是我沒(méi) commit?分支搞錯(cuò)了皱坛?
3.遇到問(wèn)題無(wú)法在線上 debug报慕,難道只能通過(guò)加日志再重新發(fā)布嗎?
4.線上遇到某個(gè)用戶的數(shù)據(jù)處理有問(wèn)題蜻拨,但線上同樣無(wú)法 debug池充,線下無(wú)法重現(xiàn)!
5.是否有一個(gè)全局視角來(lái)查看系統(tǒng)的運(yùn)行狀況官觅?
6.有什么辦法可以監(jiān)控到JVM的實(shí)時(shí)運(yùn)行狀態(tài)纵菌?
7.怎么快速定位應(yīng)用的熱點(diǎn)阐污,生成火焰圖休涤?
8.怎樣直接從JVM內(nèi)查找某個(gè)類的實(shí)例?

更多細(xì)節(jié)請(qǐng)參考官網(wǎng):https://arthas.aliyun.com/doc/

2.下載安裝

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

啟動(dòng)后選擇第一個(gè)進(jìn)程進(jìn)入笛辟,這里輸入1選第一個(gè)進(jìn)程


也可以通過(guò)jps查詢到pid先功氨,然后直接綁定pid和port

java -jar arthas-boot.jar --http-port {port} {pid}

3.常用命令

3.1 dashboard

輸入dashboard,按回車/enter手幢,會(huì)展示當(dāng)前進(jìn)程的信息捷凄,按ctrl+c可以中斷執(zhí)行

3.2 thread

這個(gè)命令和jstack很相似,但是功能更加強(qiáng)大围来,主要看當(dāng)前JVM的線程堆棧信息
還可以結(jié)合使用thread -b來(lái)進(jìn)行死鎖排查跺涤。
參數(shù)解析

  • -h 顯示幫助


  • -n 指定最忙的前n個(gè)線程并打印堆棧


  • -b 找出阻塞當(dāng)前線程的線程
    這是沒(méi)有阻塞線程的效果

    運(yùn)行一個(gè)死鎖代碼再試一下

    出現(xiàn)死鎖匈睁,會(huì)有紅色字體提醒,這個(gè)阻塞的線程已經(jīng)被另外一個(gè)線程阻塞
  • -i 指定cpu占比統(tǒng)計(jì)的采樣時(shí)間間隔桶错,單位為毫秒
    每隔1000毫秒進(jìn)行采樣航唆,顯示最占CPU時(shí)間的前2個(gè)線程
  • --state 線程狀態(tài)

  • <id> 顯示線程堆
    先通過(guò)dashboard查到一個(gè)線程id

3.3 jvm

這個(gè)命令可以查看到非常詳細(xì)的jvm信息


3.4 jad

反編譯指定已加載類的源碼


[arthas@36092]$ jad sandwich.test10.StopWorld

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@18b4aac2
  +-sun.misc.Launcher$ExtClassLoader@631cd9f3

Location:
/D:/git/test/target/classes/

       /*
        * Decompiled with CFR.
        */
       package sandwich.test10;

       import java.util.LinkedList;
       import java.util.List;

       public class StopWorld {
           public static void main(String[] args) {
               FillListThread fillListThread = new FillListThread();
               TimerThread timerThread = new TimerThread();
/*61*/         fillListThread.start();
/*62*/         timerThread.start();
           }

           public static class TimerThread
           extends Thread {
               public static final long startTime = System.currentTimeMillis();

               @Override
               public void run() {
                   while (true) {
                       try {
                           while (true) {
                               long t = System.currentTimeMillis() - startTime;
                               Thread.sleep(1000L);
                           }
                       }
                       catch (InterruptedException e) {
                           e.printStackTrace();
                           continue;
                       }
                       break;
                   }
               }
           }

           public static class FillListThread
           extends Thread {
               List<byte[]> list = new LinkedList<byte[]>();

               @Override
               public void run() {
                   while (true) {
                       try {
                           while (true) {
                               if (this.list.size() * 512 / 1024 / 1024 >= 1000) {
                                   System.out.println("Going to clear list, list size: " + this.list.size());
                                   this.list.clear();
                                   System.out.println("List is clean, list size: " + this.list.size());
                               }
                               for (int i = 0; i < 100; ++i) {
                                   byte[] bytes = new byte[1024];
                                   this.list.add(bytes);
                               }
                               Thread.sleep(1L);
                           }
                       }
                       catch (InterruptedException e) {
                           e.printStackTrace();
                           continue;
                       }
                       break;
                   }
               }
           }
       }

Affect(row-cnt:3) cost in 221 ms.

3.5 trace

使用trace命令可以跟蹤統(tǒng)計(jì)方法耗時(shí)。

trace {class-pattern} {method-pattern} -n {命令執(zhí)行次數(shù)} --skipJDKMethod false

參數(shù)名稱 參數(shù)說(shuō)明
class-pattern 類名表達(dá)式匹配
method-pattern 方法名表達(dá)式匹配
condition-express 條件表達(dá)式
[E] 開啟正則表達(dá)式匹配院刁,默認(rèn)為通配符匹配
[n:] 命令執(zhí)行次數(shù)
#cost 方法執(zhí)行耗時(shí)

這個(gè)命令就可以統(tǒng)計(jì)出來(lái)一個(gè)類里面的一些高耗時(shí)的方法


3.6 watch

watch讓你能方便的觀察到指定函數(shù)的調(diào)用情況糯钙。能觀察到的范圍為:返回值、拋出異常退腥、入?yún)⑷伟叮ㄟ^(guò)編寫 OGNL 表達(dá)式進(jìn)行對(duì)應(yīng)變量的查看

watch 的參數(shù)比較多,主要是因?yàn)樗茉?4 個(gè)不同的場(chǎng)景觀察對(duì)象

參數(shù)名稱 參數(shù)說(shuō)明
class-pattern 類名表達(dá)式匹配
method-pattern 函數(shù)名表達(dá)式匹配
express 觀察表達(dá)式狡刘,默認(rèn)值:{params, target, returnObj}
condition-express 條件表達(dá)式
[b] 函數(shù)調(diào)用之前觀察
[e] 函數(shù)異常之后觀察
[s] 函數(shù)返回之后觀察
[f] 函數(shù)結(jié)束之后(正常返回和異常返回)觀察
[E] 開啟正則表達(dá)式匹配享潜,默認(rèn)為通配符匹配
[x:] 指定輸出結(jié)果的屬性遍歷深度,默認(rèn)為 1

剛開始監(jiān)聽是這樣的


當(dāng)方法被調(diào)用完才會(huì)打印出調(diào)用信息嗅蔬,以下是能過(guò)rest api call了兩次的信息


3.7 monitor

實(shí)時(shí)返回命令是輸入之后立即返回米碰,而非實(shí)時(shí)返回的命令,則是不斷的等待目標(biāo) Java 進(jìn)程返回信息购城,直到用戶輸入 Ctrl+C 為止吕座。

服務(wù)端是以任務(wù)的形式在后臺(tái)跑任務(wù),植入的代碼隨著任務(wù)的中止而不會(huì)被執(zhí)行瘪板,所以任務(wù)關(guān)閉后吴趴,不會(huì)對(duì)原有性能產(chǎn)生太大影響,而且原則上侮攀,任何Arthas命令不會(huì)引起原有業(yè)務(wù)邏輯的改變锣枝。

方法擁有一個(gè)命名參數(shù) [c:],意思是統(tǒng)計(jì)周期(cycle of output)兰英,擁有一個(gè)整型的參數(shù)值

參數(shù)名稱 參數(shù)說(shuō)明
class-pattern 類名表達(dá)式匹配
method-pattern 方法名表達(dá)式匹配
condition-express 條件表達(dá)式
[E] 開啟正則表達(dá)式匹配撇叁,默認(rèn)為通配符匹配
[c:] 統(tǒng)計(jì)周期,默認(rèn)值為120秒
[b] 方法調(diào)用之前計(jì)算condition-express
監(jiān)控項(xiàng) 說(shuō)明
timestamp 時(shí)間戳
class Java類
method 方法(構(gòu)造方法畦贸、普通方法)
total 調(diào)用次數(shù)
success 成功次數(shù)
fail 失敗次數(shù)
rt 平均RT
fail-rate 失敗率

3.8 vmoption

查看陨闹,更新JVM診斷相關(guān)的參數(shù)

[arthas@13412]$ vmoption
 KEY                                                                            VALUE                                                                          ORIGIN                                                                         WRITEABLE
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 HeapDumpBeforeFullGC                                                           false                                                                          DEFAULT                                                                        true
 HeapDumpAfterFullGC                                                            false                                                                          DEFAULT                                                                        true
 HeapDumpOnOutOfMemoryError                                                     false                                                                          DEFAULT                                                                        true
 HeapDumpPath                                                                                                                                                  DEFAULT                                                                        true
 CMSAbortablePrecleanWaitMillis                                                 100                                                                            DEFAULT                                                                        true
 CMSWaitDuration                                                                2000                                                                           DEFAULT                                                                        true
 CMSTriggerInterval                                                             -1                                                                             DEFAULT                                                                        true
 PrintGC                                                                        false                                                                          DEFAULT                                                                        true
 PrintGCDetails                                                                 false                                                                          DEFAULT                                                                        true
 PrintGCDateStamps                                                              false                                                                          DEFAULT                                                                        true
 PrintGCTimeStamps                                                              false                                                                          DEFAULT                                                                        true
 PrintGCID                                                                      false                                                                          DEFAULT                                                                        true
 PrintClassHistogramBeforeFullGC                                                false                                                                          DEFAULT                                                                        true
 PrintClassHistogramAfterFullGC                                                 false                                                                          DEFAULT                                                                        true
 PrintClassHistogram                                                            false                                                                          DEFAULT                                                                        true
 MinHeapFreeRatio                                                               0                                                                              DEFAULT                                                                        true
 MaxHeapFreeRatio                                                               100                                                                            DEFAULT                                                                        true
 PrintConcurrentLocks                                                           false                                                                          DEFAULT                                                                        true
 UnlockCommercialFeatures                                                       false                                                                          DEFAULT                                                                        true

3.9 sc

查看JVM已加載的類信息,可以根據(jù)包名模糊查詢

[arthas@13412]$ sc com.alibaba.arthas.deps.ch.qos.logback.classic.*
com.alibaba.arthas.deps.ch.qos.logback.classic.BasicConfigurator
com.alibaba.arthas.deps.ch.qos.logback.classic.Level
com.alibaba.arthas.deps.ch.qos.logback.classic.Logger
com.alibaba.arthas.deps.ch.qos.logback.classic.LoggerContext
com.alibaba.arthas.deps.ch.qos.logback.classic.PatternLayout
com.alibaba.arthas.deps.ch.qos.logback.classic.boolex.JaninoEventEvaluator
com.alibaba.arthas.deps.ch.qos.logback.classic.encoder.PatternLayoutEncoder
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.JoranConfigurator
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.ConfigurationAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.ConsolePluginAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.ContextNameAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.EvaluatorAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.InsertFromJNDIAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.JMXConfiguratorAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.LevelAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.LoggerAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.LoggerContextListenerAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.ReceiverAction
com.alibaba.arthas.deps.ch.qos.logback.classic.joran.action.RootLoggerAction
com.alibaba.arthas.deps.ch.qos.logback.classic.layout.TTLLLayout
com.alibaba.arthas.deps.ch.qos.logback.classic.pattern.Abbreviator
com.alibaba.arthas.deps.ch.qos.logback.classic.pattern.CallerDataConverter
com.alibaba.arthas.deps.ch.qos.logback.classic.pattern.ClassOfCallerConverter
com.alibaba.arthas.deps.ch.qos.logback.classic.pattern.ClassicConverter
com.alibaba.arthas.deps.ch.qos.logback.classic.pattern.ContextNameConverter
com.alibaba.arthas.deps.ch.qos.logback.classic.pattern.DateConverter
...

3.10 sm

查看已加載類的方法信息

[arthas@13412]$ sm com.alibaba.arthas.deps.ch.qos.logback.classic.Level
com.alibaba.arthas.deps.ch.qos.logback.classic.Level <init>(ILjava/lang/String;)V
com.alibaba.arthas.deps.ch.qos.logback.classic.Level toString()Ljava/lang/String;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level valueOf(Ljava/lang/String;)Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level readResolve()Ljava/lang/Object;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level toLocationAwareLoggerInteger(Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;)I
com.alibaba.arthas.deps.ch.qos.logback.classic.Level fromLocationAwareLoggerInteger(I)Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level toLevel(I)Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level toLevel(Ljava/lang/String;Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;)Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level toLevel(Ljava/lang/String;)Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level toLevel(ILcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;)Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level toInt()I
com.alibaba.arthas.deps.ch.qos.logback.classic.Level toInteger()Ljava/lang/Integer;
com.alibaba.arthas.deps.ch.qos.logback.classic.Level isGreaterOrEqual(Lcom/alibaba/arthas/deps/ch/qos/logback/classic/Level;)Z
Affect(row-cnt:13) cost in 4 ms.

這些只是一些基礎(chǔ)命令薄坏,如果需要深入使用趋厉,還需要研究Arthas的進(jìn)階使用

4.通過(guò)瀏覽器連接arthas

Arthas目前支持Web Console,用戶在attach成功之后胶坠,可以直接訪問(wèn)
端口可以在啟動(dòng)信息里面確認(rèn)

可以填入IP君账,遠(yuǎn)程連接其它機(jī)器上的arthas,web console跟我本地訪問(wèn)的可以不相同
那我們要怎樣綁定其他端口和進(jìn)程呢沈善?
在遠(yuǎn)程服務(wù)器上啟動(dòng)arthas乡数,啟動(dòng)時(shí)要指定ip和端口椭蹄,不然不開放遠(yuǎn)程訪問(wèn),只能通過(guò)127.0.0.1訪問(wèn)

java -jar arthas-boot.jar --target-ip {ip} --http-port {port} {pid}

如下:


Web訪問(wèn)

5.Arthas idea插件

arthas-idea支持部分命令可視化



裝好插件之后就可以在類上面右鍵選擇命令了净赴,如下



選擇命令就已經(jīng)復(fù)制好命令和需要的參數(shù)了塑娇,然后去執(zhí)行這個(gè)命令
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市劫侧,隨后出現(xiàn)的幾起案子埋酬,更是在濱河造成了極大的恐慌,老刑警劉巖烧栋,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件写妥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡审姓,警方通過(guò)查閱死者的電腦和手機(jī)珍特,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)魔吐,“玉大人扎筒,你說(shuō)我怎么就攤上這事〕昴罚” “怎么了嗜桌?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)辞色。 經(jīng)常有香客問(wèn)我骨宠,道長(zhǎng),這世上最難降的妖魔是什么相满? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任层亿,我火速辦了婚禮,結(jié)果婚禮上立美,老公的妹妹穿的比我還像新娘匿又。我一直安慰自己,他們只是感情好建蹄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布碌更。 她就那樣靜靜地躺著,像睡著了一般躲撰。 火紅的嫁衣襯著肌膚如雪针贬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天拢蛋,我揣著相機(jī)與錄音,去河邊找鬼蔫巩。 笑死谆棱,一個(gè)胖子當(dāng)著我的面吹牛快压,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垃瞧,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼蔫劣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了个从?” 一聲冷哼從身側(cè)響起脉幢,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嗦锐,沒(méi)想到半個(gè)月后嫌松,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奕污,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年萎羔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碳默。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贾陷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嘱根,到底是詐尸還是另有隱情髓废,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布该抒,位于F島的核電站瓦哎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏柔逼。R本人自食惡果不足惜蒋譬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望愉适。 院中可真熱鬧犯助,春花似錦、人聲如沸维咸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)癌蓖。三九已至瞬哼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間租副,已是汗流浹背坐慰。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留用僧,地道東北人结胀。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓赞咙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親糟港。 傳聞我的和親對(duì)象是個(gè)殘疾皇子攀操,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容