最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何使用Arthas(阿爾薩斯)排查Java程序線上問(wèn)題

 更新時(shí)間:2026年01月15日 09:19:52   作者:紅衣女妖仙  
Arthas是一款線上監(jiān)控診斷產(chǎn)品,通過(guò)全局視角實(shí)時(shí)查看應(yīng)用 load、內(nèi)存、gc、線程的狀態(tài)信息,并能在不修改應(yīng)用代碼的情況下,對(duì)業(yè)務(wù)問(wèn)題進(jìn)行診斷,這篇文章主要介紹了如何使用Arthas(阿爾薩斯)排查Java程序線上問(wèn)題的相關(guān)資料,需要的朋友可以參考下

前言:

Arthas(阿爾薩斯)是阿里巴巴開(kāi)源的一款用于線上診斷 Java 程序的工具,通過(guò)全局視角實(shí)時(shí)查看應(yīng)用程序加載、內(nèi)存、垃圾回收和線程的狀態(tài)等信息,并能在不修改程序代碼和不中斷程序運(yùn)行的情況下,對(duì)程序運(yùn)行問(wèn)題進(jìn)行排查,包括查看方法調(diào)用的出入?yún)ⅰ惓?,監(jiān)測(cè)方法執(zhí)行耗時(shí),類加載等信息,能夠大大提升線上問(wèn)題排查的效率。

通常,本地開(kāi)發(fā)環(huán)境無(wú)法訪問(wèn)生產(chǎn)環(huán)境。如果在生產(chǎn)環(huán)境中遇到問(wèn)題,則無(wú)法使用本地 IDE 遠(yuǎn)程調(diào)試(部分情況下可通過(guò)本地 IDE 遠(yuǎn)程 Debug 生產(chǎn)服務(wù)),并且,大部分情況下并不允許在生產(chǎn)環(huán)境中調(diào)試,因?yàn)樗赡軙?huì)影響業(yè)務(wù),甚至中斷程序。

一般情況下,若遇到生產(chǎn)問(wèn)題,則會(huì)在測(cè)試環(huán)境中嘗試復(fù)現(xiàn)生產(chǎn)問(wèn)題,但某些問(wèn)題在不同環(huán)境中不能輕易復(fù)現(xiàn)甚至不能復(fù)現(xiàn)。

故,若你想在生產(chǎn)環(huán)境中排查問(wèn)題,尤其是 JVM 問(wèn)題,那么不妨試試 Arthas,無(wú)需重啟程序,無(wú)需修改代碼,無(wú)需中斷業(yè)務(wù),如菲奧娜的被動(dòng) 決斗之舞 般,可輕松發(fā)現(xiàn)正在運(yùn)行的程序所漏出破綻。

1 使用場(chǎng)景

  • 1、這個(gè)類是從哪個(gè) jar 包加載的?為什么會(huì)報(bào)各種類相關(guān)的 Exception
  • 2、我改的代碼為什么沒(méi)有執(zhí)行到?難道是我沒(méi) commit 或是部署沒(méi)生效?
  • 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)行狀態(tài)?
  • 6、有什么辦法可以監(jiān)控到 JVM 的實(shí)時(shí)運(yùn)行狀態(tài)?
  • 7、怎么快速定位應(yīng)用的熱點(diǎn),生成火焰圖?
  • 8、怎樣直接從 JVM 內(nèi)查找某個(gè)類的實(shí)例?
  • 9、面試時(shí)老被問(wèn)到生產(chǎn)問(wèn)題怎么排查?JVM 如何調(diào)優(yōu)?甚至剛畢業(yè)就要求三年經(jīng)驗(yàn)!

提示

以上所有問(wèn)題,通過(guò) Arthas 都可以解決!

2 下載安裝

2.1 下載

2.1.1 從 maven 倉(cāng)庫(kù)下載

下載地址為 https://arthas.aliyun.com/download/latest_version?mirror=aliyun,下載文件為 zip 壓縮包,下載后解壓即可。

2.1.2 從 github relese 下載

下載地址為 https://github.com/alibaba/arthas/releases。

2.1.3 命令行下載

執(zhí)行以下命令下載:

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

# 或
# 推薦以此方式安裝
curl -O https://arthas.aliyun.com/arthas-boot.jar

2.2 啟動(dòng)

2.2.1 用 as.sh 啟動(dòng)

解壓后,執(zhí)行文件夾內(nèi)的 as.sh 腳本文件啟動(dòng),命令如下:

./as.sh
# 或
./as.sh -h   # -h 可打印幫助信息

2.2.2 用 arthsa-boot 啟動(dòng)

arthas 的啟動(dòng)實(shí)際上是執(zhí)行 arthas-boot.jar jar 包,解壓后,文件夾內(nèi)有 arthas-boot.jar,直接使用以下命令啟動(dòng):

java -jar arthas-boot.jar

3 快速入門

3.1 啟動(dòng) arthas

使用 java -jar arthas-boot.jar 命令啟動(dòng) arthas 程序后會(huì)輸出以下內(nèi)容,其中 1 2 3 4 5 編號(hào)所標(biāo)識(shí)的 java 進(jìn)程則是當(dāng)前可監(jiān)測(cè)的正在運(yùn)行的 java 程序。

??注意

請(qǐng)注意,在使用 java -jar arthas-boot.jar 命令啟動(dòng) arthas 時(shí),當(dāng)前用戶需要和目標(biāo)進(jìn)程的啟動(dòng)用戶保持一致,否則可能會(huì) attach(附加)失敗。若 attach 不上目標(biāo)進(jìn)程,則可查看 ~/logs/arthas/ 目錄下的日志。

編號(hào) 4 所標(biāo)識(shí)的 UserCenterApplication 程序則是此次的 demo,輸入 4 再回車后,arthas 便會(huì)附加到目標(biāo)進(jìn)程上,并輸出相關(guān)日志:

3.2 查看進(jìn)程信息

可通過(guò) dashboard 命令查看當(dāng)前進(jìn)程對(duì)應(yīng)控制面板,即展示當(dāng)前進(jìn)程的實(shí)時(shí)信息,包括線程的名稱、運(yùn)行狀態(tài)、CPU 占用等信息,內(nèi)存信息,運(yùn)行時(shí)環(huán)境等信息。按 ctrl + c 可中斷執(zhí)行。

關(guān)于 dashboard 命令的詳細(xì)信息將在下文進(jìn)行說(shuō)明。

3.3 查看線程堆棧

通過(guò) thread 命令加線程 ID 即可查看某個(gè)線程的當(dāng)前堆棧信息。

3.4 反編譯類

通過(guò) jad 命令加全類名,即可查看某個(gè)已加載類的反編譯信息。

3.5 退出 arthas

如果只退出針對(duì)當(dāng)前進(jìn)程的連接,則使用 exitquit 即可,執(zhí)行后 arthas 依舊會(huì) attach 到目標(biāo)進(jìn)程上,端口會(huì)保持開(kāi)放,下次連接時(shí)可直接連接上。若想完全退出 arthas,則執(zhí)行 stop 命令即可。

4 命令列表

4.1 基礎(chǔ)命令

  • base64base64 編碼轉(zhuǎn)換,和 linux 中的 base64 命令類似。
  • cat:打印文件內(nèi)容,和 linux 中的 cat 命令類似。
  • cls:清空當(dāng)前屏幕區(qū)域。
  • echo:打印參數(shù),和 linux 中的 echo 命令類似。
  • grep:匹配查找,和 linux 中的 grep 命令類似。
  • help:查看命令幫助信息。
  • history:打印命令歷史。
  • keymaparthas 快捷鍵列表及自定義快捷鍵。
  • pwd:返回當(dāng)前的工作目錄,和 linux 中的 pwd 命令類似。
  • reset:重置增強(qiáng)類,將被 arthas 增強(qiáng)過(guò)的類全部還原,arthas 服務(wù)類關(guān)閉時(shí)會(huì)重置所有增強(qiáng)過(guò)的類。
  • session:查看當(dāng)前會(huì)話的信息。
  • stop:關(guān)閉 arthas 服務(wù)端,所有 arthas 客戶端全部退出。
  • tee:復(fù)制標(biāo)準(zhǔn)輸入到標(biāo)準(zhǔn)輸出到指定的文件,和 linux 中的 tee 命令類似。
  • version:輸出附加到當(dāng)前進(jìn)程的 arthas 的版本號(hào)。

4.2 jvm 相關(guān)

  • dashboard:當(dāng)前進(jìn)程的實(shí)時(shí)信息面板。
  • getstatic:查看類的靜態(tài)屬性。
  • heapdump:dump java heap,類似 jmap 命令的 heap dump 功能,用于生成某一時(shí)刻的對(duì)內(nèi)存快照。
  • jvm:查看當(dāng)前 jvm 信息。
  • logger:查看和修改 logger
  • mbean:查看 Mbean 的信息。
  • memory:查看 jvm 的內(nèi)存信息。
  • ognl:執(zhí)行 ognl 表達(dá)式。
  • perfcounter:查看當(dāng)前 jvm 的 Perf Counter 信息。
  • sysenv:查看 jvm 的環(huán)境變量。
  • sysprop:查看和修改 jvm 的系統(tǒng)屬性。
  • thread:查看當(dāng)前 jvm 中某個(gè)線程的堆棧信息。
  • vmoption:查看和修改 jvm 里診斷相關(guān)的 option
  • vmtool:從 jvm 里查詢對(duì)象,執(zhí)行 forceGc。

4.3 class/classloader 相關(guān)

  • classloader:查看 classloader 的繼承樹(shù),urls,類加載信息,使用 classloadergetResource。
  • dumpdump 已加載類的 byte code 到指定目錄。
  • jad:反編譯指定已加載類的源碼。
  • mc:內(nèi)存編譯器,內(nèi)存編譯 .java 文件為 .class 文件。
  • redefine:加載外部的 .class 文件,redefine 到 jvm 里。
  • retransform:加載外部的 .class 文件,retransform 到 jvm 里。
  • sc:查看 jvm 已加載的類的信息。
  • sm:查看 jvm 已加載的類的方法信息。

4.4 monitor/watch/trace 相關(guān)

??注意

請(qǐng)注意,這些命令都是通過(guò)字節(jié)碼增強(qiáng)技術(shù)來(lái)實(shí)現(xiàn)的,會(huì)在指定類的方法中插入一些切面來(lái)實(shí)現(xiàn)數(shù)據(jù)統(tǒng)計(jì)和觀測(cè),因此在線上、預(yù)發(fā)使用時(shí),請(qǐng)盡量明確需要觀測(cè)的類、方法以及條件,診斷結(jié)束要執(zhí)行 stop 或?qū)⒃鰪?qiáng)過(guò)的類執(zhí)行 reset 命令。

  • monitor:方法執(zhí)行監(jiān)控。
  • stack:輸出當(dāng)前方法被調(diào)用的調(diào)用路徑。
  • trace:方法內(nèi)部調(diào)用路徑,并輸出方法路徑上的每個(gè)節(jié)點(diǎn)的執(zhí)行耗時(shí)。
  • tt:方法執(zhí)行數(shù)據(jù)的時(shí)空隧道,記錄下指定方法每次調(diào)用的入?yún)⒑头祷匦畔?,并能?duì)這些不同時(shí)間下的調(diào)用進(jìn)行觀測(cè)。
  • watch:方法執(zhí)行數(shù)據(jù)觀測(cè),可觀測(cè) 返回值、拋出異常、入?yún)⒌取?/li>

4.5 profiler/火焰圖

  • profiler:使用 async-profiler 對(duì)應(yīng)用采樣,生成火焰圖。關(guān)于 async-profiler 更多的信息,可查看 https://github.com/jvm-profiling-tools/async-profiler。
  • jfr:動(dòng)態(tài)開(kāi)啟關(guān)閉 JFR 記錄。

4.6 后臺(tái)異步任務(wù)

當(dāng)線上出現(xiàn)偶發(fā)問(wèn)題,比如需要 watch 某個(gè)條件,而這個(gè)條件一天可能才會(huì)出現(xiàn)一次時(shí),則可以使用此類命令。

  • 使用 > 將結(jié)果重寫向到日志文件,使用 & 指定命令是后臺(tái)運(yùn)行,session 斷開(kāi)不影響任務(wù)執(zhí)行(生命周期默認(rèn)為 1 天)。
  • jobs:列出所有 job
  • kill:強(qiáng)制終止任務(wù)。
  • fg:將暫停的任務(wù)拉到前臺(tái)執(zhí)行。
  • bg:將暫停的任務(wù)放到后臺(tái)執(zhí)行。

5 常用命令

5.1 dashboard

查看當(dāng)前進(jìn)程對(duì)應(yīng)控制面板,即展示當(dāng)前進(jìn)程的實(shí)時(shí)信息,包括線程的名稱、運(yùn)行狀態(tài)、cpu 占用等信息,內(nèi)存信息,運(yùn)行時(shí)環(huán)境等信息。按 ctrl + c 可中斷執(zhí)行。

參數(shù)說(shuō)明:

  • [i:]:刷新實(shí)時(shí)數(shù)據(jù)的時(shí)間間隔(ms),默認(rèn) 5000ms。
  • [n:]:刷新實(shí)時(shí)數(shù)據(jù)的次數(shù)。

數(shù)據(jù)說(shuō)明:

  • ID:java 級(jí)別的線程 ID,注意這個(gè) ID 不能和 jstack 中的 nativeID 一一對(duì)應(yīng)。
  • NAME:線程名。
  • GROUP:線程組。
  • PRIORITY:線程優(yōu)先級(jí),1 ~ 10 之間的數(shù)字,越大表示優(yōu)先級(jí)越高。
  • STATE:線程的狀態(tài)。
  • CPU%:線程的 cpu 使用率。比如采樣間隔 1000ms,某個(gè)線程的增強(qiáng) cpu 時(shí)間為 100ms,則 cpu 使用率 = 100/1000=10%
  • DELTA_TIME:上次采樣之后線程運(yùn)行增量 cpu 時(shí)間,數(shù)據(jù)格式為 秒。
  • TIME:線程運(yùn)行總 cpu 時(shí)間,數(shù)據(jù)格式為 分:秒。
  • INTERRUPTED:線程當(dāng)前的中斷狀態(tài)。
  • DAEMON:是否為 daemon 線程。

Java 8 之后支持獲取 JVM 內(nèi)部線程 cpu 時(shí)間。JVM 內(nèi)部線程如:

  • JIT 編譯線程:如 C1 CompilerThread0,C2 CompilerThread0。
  • GC 線程:如 GC Thread0,G1 Young RemSet Sampling。
  • 其它內(nèi)部線程:如 VM Periodic Task ThreadVM Thread,Service Thread。

截圖展示:

5.2 memory

查看 JVM 內(nèi)存信息,具體字段信息可參考:

  • https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryMXBean.html#getHeapMemoryUsage()。
  • https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryMXBean.html#getHeapMemoryUsage()

截圖展示:

5.3 thread

查看當(dāng)前進(jìn)程中某個(gè)線程的堆棧信息。如 thread 45,其中 45 為線程 ID。

參數(shù)說(shuō)明:

  • id:線程 id。
  • [n:]:指定最忙的前 N 個(gè)線程并打印堆棧。
  • [b]:找出當(dāng)前阻塞其它線程的線程。
  • [i<value>]:指定 cpu 使用率統(tǒng)計(jì)的采樣間隔,單位為毫秒,默認(rèn)值為 200。
  • [--all]:顯示所有匹配的線程。

提示

這里的 cpu 使用率與 linux 命令 top -H -p <pid> 的線程 %CPU 類似,一段采樣間隔時(shí)間內(nèi),當(dāng)前 jvm 里各個(gè)線程的增量 cpu 時(shí)間與采樣間隔時(shí)間的比例。

工作原理:

  • 首先第一次采樣,獲取所有線程 cpu 時(shí)間,調(diào)用的是 java.lang.management.ThreadMXBean#getThreadCpuTime()sun.management.HotspotThreadMBean.getInternalThreadCpuTimes() 接口。
  • 然后睡眠等待一個(gè)間隔時(shí)間(默認(rèn)為 200ms,可通過(guò) -i 指定間隔時(shí)間)。
  • 再次第二次采樣,獲取所有線程的 cpu 時(shí)間,對(duì)比兩次采樣數(shù)據(jù),計(jì)算出每個(gè)線程的增量 cpu 時(shí)間。
  • 線程 cpu 使用率 = 線程增量 cpu 時(shí)間 / 采樣間隔時(shí)間 * 100%。

??注意

這個(gè)統(tǒng)計(jì)也會(huì)產(chǎn)生一定的開(kāi)銷(JDK 這個(gè)借口本身開(kāi)銷比較大),因此會(huì)看到 as 的線程占用一定的百分比,為了降低統(tǒng)計(jì)自身的開(kāi)銷所帶來(lái)的影響,建議拉長(zhǎng)采樣間隔時(shí)間,比如 5000ms。

截圖展示:

5.4 vmtool

利用 JVMTI 接口,實(shí)現(xiàn)查詢內(nèi)存對(duì)象,強(qiáng)制 GC 等功能。JVMTI 文檔見(jiàn) https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html。

參數(shù)說(shuō)明:

  • [--action]:指定操作名。
  • [--className]:指定類名。
  • [--classLoaderClass]:指定類加載器名。
  • [-c]:指定 classloaderhash 值。
  • [--limit]:限制返回值數(shù)量,以避免獲取超大數(shù)據(jù)時(shí)對(duì) jvm 造成壓力,默認(rèn)值為 10。

查詢對(duì)象截圖展示:

其它功能:

  • 強(qiáng)制 GC:

    # 可結(jié)合 vmoption 命令動(dòng)態(tài)打開(kāi) PrintGC 開(kāi)關(guān)
    vmtool --action forceGC
    
  • interrupt 指定線程:

    # thread id 通過(guò) -t 參數(shù)指定,可使用 thread 命令獲取
    vmtool --action interruptThread -t 1
    
  • glibc 釋放空閑內(nèi)存:

    # Linux man page:malloc_trim 查看 https://man7.org/linux/man-pages/man3/malloc_trim.3.html
    vmtool --action mallocTrim
    
  • glibc 內(nèi)存狀態(tài):

    # 內(nèi)存狀態(tài)會(huì)輸出到應(yīng)用的 stder。
    # Linux man page:malloc_stats 查看 https://man7.org/linux/man-pages/man3/malloc_stats.3.html
    vmtool --action mallocStats
    

5.5 jad

查看已加載到 jvm 中的類的源碼的反編譯信息。通過(guò)查看反編譯后的 java 代碼,便于分析代碼邏輯,以及確認(rèn)發(fā)布后的代碼是否為你修改的代碼。

  • 反編譯后的代碼是語(yǔ)法高亮的,便于閱讀。
  • 反編譯后的代碼可能會(huì)存在語(yǔ)法錯(cuò)誤,但不影響閱讀理解。

參數(shù)說(shuō)明:

  • class-pattern:類名表達(dá)式匹配。
  • [c:]:類所屬 ClassLoaderhashCode。
  • [classLoaderClass:]:指定執(zhí)行表達(dá)式的 ClassLoader 的 class name。
  • [E]:開(kāi)啟正則表達(dá)式匹配,默認(rèn)為通配符匹配。
  • [--lineNumber]:是否顯示行號(hào),默認(rèn)為 true。
  • [--source-only]:默認(rèn)情況下,反編譯結(jié)果里會(huì)帶有 ClassLoader 信息,可通過(guò)該命令紙打印源代碼。方便和 mc/retransform 命令結(jié)合使用。
  • [>]:將結(jié)果輸出到目標(biāo)文件,如 > Test.java。

截圖展示:

5.6 retransform

加載外部的 .class 文件,retransform jvm 已加載的類,即熱更新類,這個(gè)功能非常有用!

熱更新的操作步驟是什么呢?首先修改目標(biāo)類,然后將目標(biāo)類轉(zhuǎn)換成 .class 文件,最后再熱更新,這一系列操作都可以通過(guò)相關(guān)命令實(shí)現(xiàn)。那如果我們要修改的內(nèi)容很少,直接 vim 就可以修改,那么它的具體操作可以是這樣:

  • 1、使用 jad 命令反編譯輸出目標(biāo)類的源碼。

    jad --source-only org.xgllhz.usercenter.blog.web.controller.WebBlogController > WebBlogController.java
    
  • 2、使用 vim 命令直接修改。

  • 3、使用 mc.java 文件編譯成字節(jié)碼文件 .class

    mc WebBlogController.java -d ./
    
  • 3、使用 retransform 命令熱更新編譯后的字節(jié)碼文件。

    retransform WebBlogController.class
    

提示

若多次執(zhí)行 retransform 加載同一個(gè) class 文件,則會(huì)有多條 retransform entry。

針對(duì) retransform entry 的操作:

  • 查看 retransform entry

    retransform -l
    
  • 刪除指定 retransform entry

    # 1 為 id
    retransform -d 1
    
  • 刪除所有 retransform entry:

    retransform --deteleAll
    

消除 retransform 的影響:若對(duì)某個(gè)類執(zhí)行 retransform 之后,想消除影響,則需要:

  • 刪除這個(gè)類對(duì)應(yīng)的 retransform entry。
  • 重新出發(fā) retransform。

提示

若不清楚掉所有的 retransform entry,并重新出發(fā) retransform,則 stop 時(shí),retransform 過(guò)的類仍然生效。

retransform 的限制:

  • 不允許增加新的 field/method
  • 正在運(yùn)行的函數(shù),沒(méi)有退出則不會(huì)生效。

??注意

redefine 命令與 retransform 命令功能類似,但建議使用后者。

5.7 sc 與 sm

search class 的簡(jiǎn)寫,查看所有已加載到 jvm 中的 class 的信息。

參數(shù)說(shuō)明:

  • class-pattern:類名表達(dá)式匹配。
  • method-pattern:方法名表達(dá)式匹配。
  • [d]:輸出當(dāng)前類的詳細(xì)信息,包括這個(gè)類所加載的原始文件來(lái)源、類的聲明、加載的 classloader 等詳細(xì)信息,若一個(gè)類被多個(gè) classloader 加載,則會(huì)出現(xiàn)多次。
  • [E]:開(kāi)啟正則表達(dá)式匹配,默認(rèn)為通配符匹配。
  • [f]:輸出當(dāng)前類的成員變量信息(需要配合參數(shù) -d 一起使用)。
  • [x:]:指定輸出靜態(tài)變量時(shí)屬性的遍歷深度,默認(rèn)值為 0,即直接使用 toString 輸出。
  • [c:]:指定 classclassloaderhashCode。
  • [classLoaderClass:]:指定執(zhí)行表達(dá)式的 ClassLoader 的 class name。
  • [n:]:具有詳細(xì)信息的匹配類的最大數(shù)量,默認(rèn)值為 100.
  • [cs <arg>]:指定 class 的 ClassLoader#toString() 的返回值。

截圖展示:

??注意

smsc 命令大同小異,需要注意的是 sm 命令只能看到由當(dāng)前類所定義的方法,父類的則看不到。

5.8 stack

查看當(dāng)前方法被調(diào)用的調(diào)用路徑。

參數(shù)說(shuō)明:

  • class-pattern:類名表達(dá)式匹配。
  • method-pattern:方法名表達(dá)式匹配。
  • condition-express:條件表達(dá)式。
  • [E]:開(kāi)啟正則表達(dá)式匹配,默認(rèn)為通配符匹配。
  • [n:]:執(zhí)行次數(shù)限制。
  • [m <arg>]:指定 class 最大匹配數(shù)量,默認(rèn)值為 50。

??注意

這里重點(diǎn)要說(shuō)明的是觀察表達(dá)式,觀察表達(dá)式的構(gòu)成主要由 ognl 表達(dá)式組成,所以你可以這樣寫 {params, returnObj},只要是一個(gè)合法的 ognl 表達(dá)式,都能被正常支持。

觀察的維度也比較多,主要體現(xiàn)在參數(shù) advice 的數(shù)據(jù)結(jié)構(gòu)上。Advice 參數(shù)最主要是封裝了通知節(jié)點(diǎn)的所有信息。

截圖展示:

5.9 trace

查看方法內(nèi)部調(diào)用路徑,并輸出方法路徑上每個(gè)節(jié)點(diǎn)的耗時(shí)。該命令會(huì)主動(dòng)搜索 class-pattern / method-pattern 對(duì)應(yīng)的方法調(diào)用路徑,渲染和統(tǒng)計(jì)整個(gè)調(diào)用鏈路上的所有性能開(kāi)銷和追蹤調(diào)用鏈路。

參數(shù)說(shuō)明:

  • class-pattern:類名表達(dá)式匹配。
  • method-pattern:方法名表達(dá)式匹配。
  • condition-express:條件表達(dá)式。
  • [E]:開(kāi)啟正則表達(dá)式匹配,默認(rèn)為通配符匹配。
  • [n:]:命令執(zhí)行次數(shù),默認(rèn)值為 100.
  • #cost:方法執(zhí)行耗時(shí)。
  • [m <arg>]:指定 class 最大匹配數(shù)量,默認(rèn)值為 50。

??注意

重點(diǎn)說(shuō)明條件表達(dá)式,條件表達(dá)式主要由 ognl 表達(dá)式組成,所以你可以這樣寫 params[0]<0,只要是合法的 ognl 表達(dá)式,都能被正常支持。

很多時(shí)候我們可能只想看到某個(gè)方法的 rt 大于某個(gè)時(shí)間之后的 trace 結(jié)果,巧的是 arthas 可以按照方法執(zhí)行耗時(shí)來(lái)過(guò)濾了,比如你可以這樣寫 trace *StringUtils isBlank '#cost>100',表示當(dāng)該方法的執(zhí)行超過(guò) 100ms 時(shí)才會(huì)輸出 trace 的結(jié)果。不得不說(shuō),這個(gè)功能太牛了。

提示

stack/trace/watch 這三個(gè)命令都支持 #cost 參數(shù)。

截圖展示:

其中每個(gè)方法前的結(jié)果表示該方法在此次調(diào)用鏈路中耗時(shí)所占百分比和耗時(shí),方法后面的 #num(如 #62)表示該方法在源文件的第 num 行被調(diào)用。

5.10 watch

可觀測(cè)指定函數(shù)的調(diào)用情況,如入?yún)?、返回值、拋出異常等信息,且支?ognl 表達(dá)式。

??注意

下面有一個(gè)與 watch 命令功能相似的命令叫 tt,二者的區(qū)別是 watch 雖然很方便靈活,但需要提前想清楚觀察表達(dá)式的拼寫,這對(duì)排查問(wèn)題而言要求太高,且很多時(shí)候我們并不知道問(wèn)題出自何方,只能靠蛛絲馬跡進(jìn)行猜測(cè),但是如果能記錄下當(dāng)時(shí)方法調(diào)用的所有入?yún)⒑头祷刂?、拋出的異常等信息,那將?duì)整個(gè)問(wèn)題的思考和排查有很大幫助,沒(méi)錯(cuò)兒,tt 命令的功能就是這個(gè)。

很明顯,當(dāng)我想到寫這個(gè)醒目的??時(shí),我心思就早已飄到 tt 去了。

5.11 tt

方法執(zhí)行數(shù)據(jù)的時(shí)空隧道,記錄下指定方法每次調(diào)用的入?yún)ⅰ⒎祷刂岛彤惓5刃畔ⅲ⒛軐?duì)這些不同時(shí)間下的調(diào)用進(jìn)行觀測(cè)。

??警告

tt 命令的實(shí)現(xiàn)原理是:將函數(shù)的入?yún)?返回值等信息,保存到一個(gè) Map<Integer, TimeFragment> 中,該 map 的默認(rèn)容量大小是 100。

tt 相關(guān)功能在使用完之后,需要手動(dòng)釋放內(nèi)存,否則長(zhǎng)時(shí)間可能會(huì)導(dǎo)致 OOM,且即使退出 athas 也不會(huì)自動(dòng)清除 tt 的緩存 map

參數(shù)說(shuō)明:

  • [-t]:指定要記錄的目標(biāo)方法。
  • [-n:]:指定需要記錄的次數(shù),當(dāng)達(dá)到記錄次數(shù)時(shí) arthas 會(huì)主動(dòng)中斷 tt 命令的記錄過(guò)程,避免人工操作無(wú)法停止的情況。為什么會(huì)有這個(gè)參數(shù)呢?你是否經(jīng)歷過(guò)這樣的場(chǎng)景:當(dāng)你打開(kāi)日志想要觀察某個(gè)方法的日志時(shí),結(jié)果好不容易定位日志后瞬間就被后續(xù)的日志刷到十萬(wàn)八千里外了,沒(méi)錯(cuò)兒,這個(gè)參數(shù)就是干這個(gè)的。
  • [-m:]:指定 class 匹配的最大數(shù)量,防止匹配到的 class 數(shù)量太多導(dǎo)致 jvm 掛起,默認(rèn)值為 50。
  • [-s]:搜索表達(dá)式,如 -s 'method.name=="listBlogPage"'。
  • [-i]:查看某個(gè)時(shí)間片的詳細(xì)信息,值為該時(shí)間片的 INDEX 編號(hào)值。
  • [-p]:重新調(diào)用一次。
  • [-w]:觀察表達(dá)式。
  • [-d:]:后加 -i ,清除指定索引的 tt 記錄。
  • [--delete-all]:清除所有的 tt 記錄。

記錄調(diào)用:tt -t org.xgllhz.usercenter.blog.admin.service.impl.BlogServiceImpl listBlogPage,結(jié)果如下:

字段說(shuō)明:

  • INDEX:記錄編號(hào),每個(gè)編號(hào)對(duì)應(yīng)一次調(diào)用。
  • TIMESTAMP:方法執(zhí)行的本機(jī)時(shí)間。
  • COST(ms):方法執(zhí)行耗時(shí)。
  • IS-RET:方法是否以正常返回的形式結(jié)束。
  • IS-EXP:方法是否以拋異常的形式結(jié)束。
  • OBJECT:執(zhí)行對(duì)象的 hashCode,注意,它不是蓋對(duì)象在 jvm 中的內(nèi)存地址。
  • CLASS:執(zhí)行的類名。
  • METHOD:執(zhí)行的方法名。

查看某次調(diào)用信息:tt -i 1000,結(jié)果如下:

最后別忘了用 tt --delete-all 將所有記錄都清除,否則會(huì) OOM。

總結(jié)

到此這篇關(guān)于如何使用Arthas(阿爾薩斯)排查Java程序線上問(wèn)題的文章就介紹到這了,更多相關(guān)Arthas排查Java程序線上問(wèn)題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

金塔县| 南岸区| 石棉县| 吴堡县| 平和县| 宁远县| 永川市| 蓬溪县| 新源县| 瑞安市| 广灵县| 阿城市| 青海省| 青神县| 稻城县| 台南市| 东丰县| 汉寿县| 台湾省| 六盘水市| 辽阳市| 土默特左旗| 勃利县| 廊坊市| 秦皇岛市| 驻马店市| 油尖旺区| 禄丰县| 阿拉善右旗| 巢湖市| 普洱| 雅江县| 鹤峰县| 南安市| 乐陵市| 廉江市| 阜宁县| 泰顺县| 赤水市| 峡江县| 东莞市|