日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Arthas : 具体问题分析小册子

發(fā)布時間:2023/12/31 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Arthas : 具体问题分析小册子 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

前言

正文

準備

先給出我的測試代碼

下載并運行 Arthas

訪問 WebConsole

問題 1:這個類從哪個 jar 包加載的?為什么會報各種類相關(guān)的 Exception?

問題 2:我改的代碼為什么沒有執(zhí)行到?難道是我沒 commit?分支搞錯了?

問題 3:遇到問題無法在線上 debug,難道只能通過加日志再重新發(fā)布嗎?

問題 4:線上遇到某個用戶的數(shù)據(jù)處理有問題,但線上同樣無法 debug,線下無法重現(xiàn)!

問題 5:是否有一個全局視角來查看系統(tǒng)的運行狀況?

問題 6:有什么辦法可以監(jiān)控到JVM的實時運行狀態(tài)?

問題 7:怎么快速定位應(yīng)用的熱點,生成火焰圖?

問題 8:怎樣直接從JVM內(nèi)查找某個類的實例?


前言

Arthas?是Alibaba開源的Java診斷工具,深受開發(fā)者喜愛。

當你遇到以下類似問題而束手無策時,Arthas可以幫助你解決:

  • 這個類從哪個 jar 包加載的?為什么會報各種類相關(guān)的 Exception?

  • 我改的代碼為什么沒有執(zhí)行到?難道是我沒 commit?分支搞錯了?

  • 遇到問題無法在線上 debug,難道只能通過加日志再重新發(fā)布嗎?

  • 線上遇到某個用戶的數(shù)據(jù)處理有問題,但線上同樣無法 debug,線下無法重現(xiàn)!

  • 是否有一個全局視角來查看系統(tǒng)的運行狀況?

  • 有什么辦法可以監(jiān)控到JVM的實時運行狀態(tài)?

  • 怎么快速定位應(yīng)用的熱點,生成火焰圖?

  • 怎樣直接從JVM內(nèi)查找某個類的實例?

  • 這 8 個問題,Arthas 官方文檔(https://arthas.aliyun.com/doc)中并沒有給出答案或標準的解決方案。

    ?

    正文

    「下面是筆者結(jié)合多年使用 Arthas 的經(jīng)驗,針對這 8 個問題給出的詳細解決方案,如果有疑問歡迎評論區(qū)指出。」

    準備

    先給出我的測試代碼

    package?com.shockang.study;import?com.alibaba.fastjson.JSON; import?lombok.AccessLevel; import?lombok.Getter; import?lombok.Setter; import?lombok.ToString; import?lombok.experimental.FieldDefaults;import?java.util.List; import?java.util.concurrent.TimeUnit;public?class?ArthasDemo?{public?static?void?main(String[]?args)?{String?s?=?"[{\"name\":\"zhangsan\",\"age\":\"10\",\"telephone\":\"123456\",\"interests\":[\"sing\",\"dance\",\"rap\"]},\n"?+"{\"name\":\"lisi\",\"age\":\"20\",\"telephone\":\"123457\",\"interests\":[\"sing\",\"swim\"]},\n"?+"{\"name\":\"wangwu\",\"age\":\"30\",\"telephone\":\"123458\",\"interests\":[\"sing\",\"program\"]}]";//模擬一遍遍的調(diào)用方法的過程for?(;?;?)?{System.out.println(new?ArthasDemo().convert(s));try?{TimeUnit.SECONDS.sleep(10);}?catch?(InterruptedException?e)?{e.printStackTrace();}}}private?List<People>?convert(String?s)?{return?JSON.parseArray(s,?People.class);}@Getter@Setter@ToString@FieldDefaults(level?=?AccessLevel.PRIVATE)private?static?class?People?{/***?姓名*/String?name;/***?年齡*/String?age;/***?電話*/String?telephone;/***?興趣列表*/List<String>?interests;} }

    以下是控制臺正常打印的結(jié)果

    /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/bin/java ... [ArthasDemo.People(name=zhangsan, age=10, telephone=123456, interests=[sing, dance, rap]), ArthasDemo.People(name=lisi, age=20, telephone=123457, interests=[sing, swim]), ArthasDemo.People(name=wangwu, age=30, telephone=123458, interests=[sing, program])] [ArthasDemo.People(name=zhangsan, age=10, telephone=123456, interests=[sing, dance, rap]), ArthasDemo.People(name=lisi, age=20, telephone=123457, interests=[sing, swim]), ArthasDemo.People(name=wangwu, age=30, telephone=123458, interests=[sing, program])]

    下載并運行 Arthas

    按照下圖中的步驟,選擇一個 Java 進程進行 attach。

    下載并運行Arthas

    訪問 WebConsole

    attach 成功后可以打開谷歌瀏覽器輸入http://127.0.0.1:3658/?打開 WebConsole

    (吐槽一句 Mac OS 的 Safari 瀏覽器不支持)

    ?

    使用 WebConsole 最方便的是你可以打開多個標簽頁同時操作

    ?

    問題 1:這個類從哪個 jar 包加載的?為什么會報各種類相關(guān)的 Exception?

    這個問題我經(jīng)常在處理各種「依賴沖突」的時候遇到,有一些類的完全名稱是一模一樣,通過常規(guī)的辦法無法解決類具體從哪個 jar 包加載。

    別急,看我下面的解決辦法。

  • sc

  • 通過?sc?命令 模糊查看當前 JVM 中是否加載了包含關(guān)鍵字的類,以及獲取其完全名稱。

    ?

    注意使用?sc -d?命令,獲取 classLoaderHash,這個值在后面需要用到。

    ? sc?-d?*ArthasDemo*

    sc-d命令

  • classloader

  • 通過?classloader?查看 class 文件來自哪個 jar 包

    ?

    使用?cls?命令可以清空命令行,這個簡單的命令官方文檔居然找不到。。。

    ? ?

    注意?classloader -c?后面的值填上面第一步中獲取到的 Hash 值,class 文件路徑使用'/'分割,且必須以.class 結(jié)尾。

    ? [arthas@3633]$?classloader?-c?18b4aac2?-r?com/shockang/study/ArthasDemo.class file:/Users/shockang/code/concurrentbook/target/classes/com/shockang/study/ArthasDemo.class Affect(row-cnt:1)?cost?in?0?ms.

    上面是顯示 class 文件路徑的,如果 class 文件來自 jar 包,可以顯示 jar 包路徑,例如官方文檔給的例子:

    $?classloader?-c?1b6d3586?-r?java/lang/String.class jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/String.class

    問題 2:我改的代碼為什么沒有執(zhí)行到?難道是我沒 commit?分支搞錯了?

    推薦使用?watch?和?tt?命令,非常好用。

    這兩個命令都是用來查看方法調(diào)用過程的,不同的是?watch?命令是調(diào)用一次打印一次方法的調(diào)用情況,而?tt?命令可以先生成一個不斷增加的調(diào)用列表,然后指定其中某一項進行觀測。

  • 使用?watch?命令查看方法調(diào)用情況。我們要查看 ArthasDemo 這個類里面的 convert 方法調(diào)用情況。

  • watch命令

    watch?com.shockang.study.ArthasDemo?convert?"{params,target,returnObj}"?-f?-x?4

    watch?后面跟上完全類名和方法名,以及一個 OGNL 的表達式,-f 表示不論正常返回還是異常返回都進行觀察,-x 表示輸出結(jié)果的屬性遍歷深度,默認為 1,

    ?

    建議無腦寫 4 就行,這是筆者經(jīng)驗來看最大的遍歷深度,再大就不支持了

    ?
  • 使用?tt?命令來觀測方法調(diào)用情況,tt?命令可以查看「多次調(diào)用」并選擇其中一個進行觀測,但是如果輸出結(jié)果是多層嵌套就沒辦法看了,而?watch?可以查看「多層嵌套」的結(jié)果。

  • ?

    使用 tt -t 記錄下當前方法的每次調(diào)用環(huán)境現(xiàn)場

    ?

    tt -t命令

    tt?-t?com.shockang.study.ArthasDemo?convert

    TIMESTAMP表示方法調(diào)用發(fā)生的時間,COST 表示調(diào)用耗時(ms),IS-RET表示是否正常返回,IS-EXP 表示是否異常返回,OBJECT 表示對象的 HASH 值

    ?

    對于具體一個時間片的信息而言,你可以通過 -i 參數(shù)后邊跟著對應(yīng)的 INDEX 編號查看到他的詳細信息

    ?

    tt-i命令

    ?

    圖中之所以可以打印興趣列表,是調(diào)用了其 toString 方法,如果沒有重寫 java.lang.Object 類的 toString 方法,只會看到 hash 值。

    ?
  • 如何判斷代碼是否已經(jīng)提交?

  • 通過?jad --source-only?可以查看源代碼。

    [arthas@3633]$?jad?--source-only?com.shockang.study.ArthasDemo/**?Decompiled?with?CFR.*/package?com.shockang.study;import?com.alibaba.fastjson.JSON;import?java.util.List;import?java.util.concurrent.TimeUnit;public?class?ArthasDemo?{public?static?void?main(String[]?args)?{ /*15*/?????????String?s?=?"[{\"name\":\"zhangsan\",\"age\":\"10\",\"telephone\":\"123456\",\"interests\":[\"sing\",\"dance\",\"rap\"]},\n{\"name\":\"lisi\",\"age\":\"20 \",\"telephone\":\"123457\",\"interests\":[\"sing\",\"swim\"]},\n{\"name\":\"wangwu\",\"age\":\"30\",\"telephone\":\"123458\",\"interests\":[\"sing\",\"program\"]}]";while?(true)?{ /*20*/?????????????System.out.println(new?ArthasDemo().convert(s));try?{ /*22*/?????????????????TimeUnit.SECONDS.sleep(10L); /*25*/?????????????????continue;}catch?(InterruptedException?e)?{ /*24*/?????????????????e.printStackTrace();continue;}break;}}private?List<People>?convert(String?s)?{ /*30*/?????????return?JSON.parseArray(s,?People.class);}private?static?class?People?{private?String?name;private?String?age;private?String?telephone;private?List<String>?interests;private?People()?{}public?String?toString()?{return?"ArthasDemo.People(name="?+?this.getName()?+?",?age="?+?this.getAge()?+?",?telephone="?+?this.getTelephone()?+?",?interests="?+?this.getIntere sts()?+?")";}public?String?getName()?{return?this.name;}public?void?setName(String?name)?{this.name?=?name;}public?String?getAge()?{return?this.age;}public?String?getTelephone()?{return?this.telephone;}public?List<String>?getInterests()?{return?this.interests;}public?void?setAge(String?age)?{this.age?=?age;}public?void?setTelephone(String?telephone)?{this.telephone?=?telephone;}public?void?setInterests(List<String>?interests)?{this.interests?=?interests;}}}[arthas@3633]$

    問題 3:遇到問題無法在線上 debug,難道只能通過加日志再重新發(fā)布嗎?

    通過上面問題 2 的?watch?和?tt?命令可以查看方法調(diào)用情況。

    此外,可以通過?redefine?命令「熱替換」線上的代碼,注意應(yīng)用重啟之后會失效,這在某些緊急情況下會有奇效。

    比如說我們修改一下方法體里面的代碼,加了一行日志打印:

    ????private?List<People>?convert(String?s)?{System.out.println(s);return?JSON.parseArray(s,?People.class);}

    這時我們就可以將新代碼編譯后的 class 文件熱替換正在運行的 ArthasDemo 的代碼。

    redefine命令

    熱替換 JVM 內(nèi)存中(方法區(qū))加載的類

    從這張圖可以明顯的看出,明明源碼中沒有打印字符串 s 的邏輯,但是控制臺還是打印了字符串,因為我們已經(jīng)熱替換了 JVM 內(nèi)存中(方法區(qū))加載的類。

    問題 4:線上遇到某個用戶的數(shù)據(jù)處理有問題,但線上同樣無法 debug,線下無法重現(xiàn)!

    這個問題沒有完美的解決辦法

    參考一下問題 2 和問題 3的解決方案

    推薦使用?tt?命令并將命令行返回結(jié)果輸出到一個文件中,后續(xù)可以選擇異常的一行記錄使用?tt -i?命令進行深入的分析。

    tee指令會從標準輸入設(shè)備讀取數(shù)據(jù),將其內(nèi)容輸出到標準輸出設(shè)備,同時保存成文件。

    tee命令

    tt?-t?com.shockang.study.ArthasDemo?convert?|?tee?/Users/shockang/Downloads/log

    此外還可以使用?monitor?命令統(tǒng)計方法調(diào)用成功失敗情況。

    monitor命令

    monitor?-c?30?com.shockang.study.ArthasDemo?convert?|?tee?/Users/shockang/Downloads/log1 ?

    -c 后面接統(tǒng)計周期,默認值為120秒

    ?

    問題 5:是否有一個全局視角來查看系統(tǒng)的運行狀況?

    使用?dashboard?命令可以查看當前系統(tǒng)的實時數(shù)據(jù)面板, 當運行在Ali-tomcat時,會顯示當前tomcat的實時信息,如HTTP請求的qps, rt, 錯誤數(shù), 線程池信息等等。

    dashboard實時數(shù)據(jù)面板

    從圖中可以看到線程情況,內(nèi)存使用情況,系統(tǒng)參數(shù)等。

    問題 6:有什么辦法可以監(jiān)控到JVM的實時運行狀態(tài)?

    使用?jvm?命令可以查看 JVM 的實時運行狀態(tài)。

    JVM 的實時運行狀態(tài)

    問題 7:怎么快速定位應(yīng)用的熱點,生成火焰圖?

    profiler?命令支持生成應(yīng)用熱點的火焰圖。本質(zhì)上是通過不斷的采樣,然后把收集到的采樣結(jié)果生成火焰圖。

    ?

    默認情況下,生成的是 cpu 的火焰圖,即 event 是 cpu,可以用--event 參數(shù)來指定。注意不同系統(tǒng)支持的 event 不同

    ?

    ?默認情況下,arthas使用3658端口,則可以打開:http://localhost:3658/arthas-output/?查看到arthas-output目錄下面的profiler結(jié)果:

    profiler目錄

    選擇一項點擊

    profiler結(jié)果圖

    問題 8:怎樣直接從JVM內(nèi)查找某個類的實例?

    使用?vmtool?可以達成目的

    ?

    這個功能是 Arthas 3.5.1 新增的。可以參考官方文檔 https://arthas.aliyun.com/doc/vmtool.html#id1

    ? $?vmtool?--action?getInstances?--className?java.lang.String?--limit?10 @String[][@String[com/taobao/arthas/core/shell/session/Session],@String[com.taobao.arthas.core.shell.session.Session],@String[com/taobao/arthas/core/shell/session/Session],@String[com/taobao/arthas/core/shell/session/Session],@String[com/taobao/arthas/core/shell/session/Session.class],@String[com/taobao/arthas/core/shell/session/Session.class],@String[com/taobao/arthas/core/shell/session/Session.class],@String[com/],@String[java/util/concurrent/ConcurrentHashMap$ValueIterator],@String[java/util/concurrent/locks/LockSupport], ]

    通過?--limit參數(shù),可以限制返回值數(shù)量,避免獲取超大數(shù)據(jù)時對JVM造成壓力。默認值是10。

    如果想精確的定位到具體的類實例,可以通過指定 classloader name 或者 classloader hash,如下所示:

    vmtool?--action?getInstances?--classLoaderClass?org.springframework.boot.loader.LaunchedURLClassLoader?--className?org.springframework.context.ApplicationContext vmtool?--action?getInstances?-c?19469ea2?--className?org.springframework.context.ApplicationContext ?

    獲取 classloader hash 的方法請參考上面的問題 1

    ?

    vmtool 還有個不錯的功能,可以「強制進行GC」,這在某些生產(chǎn)環(huán)境內(nèi)存緊張的情況下有奇效。

    vmtool?--action?forceGc

    總結(jié)

    以上是生活随笔為你收集整理的Arthas : 具体问题分析小册子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。