arthas使用總結


引言

這里記錄一下我在使用 arthas 排查現場問題時, 使用的幾個主要命令, 怕自己忘了, 寫下來到時候可以參考.

我的個人博客:我心永恆
原文地址:arthas 使用總結

查看類加載的信息

sc -d <ClassName>
參數名稱 參數說明
class-pattern 類名表達式匹配
method-pattern 方法名表達式匹配
[d] 輸出當前類的詳細信息, 包括這個類所加載的原始文件來源, 類的聲明, 加載的 ClassLoader 等詳細信息. 如果一個類被多個 ClassLoader 所加載, 則會出現多次
[E] 開啟正則表達式匹配, 默認為通配符匹配
[f] 輸出當前類的成員變量信息 (需要配合參數-d 一起使用)
[x:] 指定輸出靜態變量時屬性的遍歷深度, 默認為 0, 即直接使用 toString 輸出
[c:] 指定 class 的 ClassLoader 的 hashcode
[classLoaderClass:] 指定執行表達式的 ClassLoader 的 class name
[n:] 具有詳細信息的匹配類的最大數量 (默認為 100)
# 模糊搜索
sc demo.*

# 打印類的詳細信息
sc -d demo.MathGame

# 打印出類的 Field 信息
sc -d -f demo.MathGame

查看類的靜態變量

# 查看類的靜態變量 getstatic ${類名} ${屬性名}
getstatic cn.lw.ClassName propName

注意 hashcode 是變化的, 需要先查看當前的 ClassLoader 信息, 使用 sc -d <ClassName> 提取對應 ClassLoader 的 hashcode. 指定 classLoader 注意 hashcode 是變化的, 需要先查看當前的 ClassLoader 信息, 使用 sc -d <ClassName> 提取對應 ClassLoader 的 hashcode. 如果你使用 -c, 你需要手動輸入 hashcode:-c <hashcode>

getstatic -c 3d4eac69 demo.MathGame random

對於只有唯一實例的 ClassLoader 可以通過--classLoaderClass 指定 class name, 使用起來更加方便:

getstatic --classLoaderClass sun.misc.Launcher$AppClassLoader demo.MathGame random

注: 這里 classLoaderClass 在 java 8 是 sun.misc.Launcher$AppClassLoader, 而 java 11 的 classloader 是 jdk.internal.loader.ClassLoaders$AppClassLoader. --classLoaderClass 的值是 ClassLoader 的類名, 只有匹配到唯一的 ClassLoader 實例時才能工作, 目的是方便輸入通用命令, 而 -c <hashcode> 是動態變化的. 如果該靜態屬性是一個復雜對象, 還可以支持在該屬性上通過 ognl 表示進行遍歷, 過濾, 訪問對象的內部屬性等操作.

查看線上代碼

jad cn.com.xxx

攔截方法的入參和出參 獲取 Spring 中的 bean 查看配置參數

記錄方法調用的信息

tt 命令的文檔在此:https://arthas.aliyun.com/doc/tt.html

tt -t demo.MathGame primeFactors -n ${記錄次數}  params[0].mobile==13989838402
# 跟蹤完了之后
tt -i 1003 -p  # -p 不需要參數, 它的意思是重新將這個方法調用一次

獲取 Spring 中的 bean

# 先這樣搞
tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod -n 3

# 隨便訪問一個 web 接口

# 然后再這樣搞
tt -i 1000 -w 'target.getApplicationContext().getBean("rocketMQConsumerManagerImpl")'

tt -i 1000 -w 'target.getApplicationContext().getBean("rocketMQConsumerManagerImpl").getTargetSource()'

tt -i 1000 -w 'target.getApplicationContext().getBean("rocketMQConsumerManagerImpl").getTargetSource().target'

P.S. 不好意思, "rocketMQConsumerManagerImpl" 這里需要加引號, 不然會報找不到.

參考:https://blog.csdn.net/yunqiinsight/article/details/86710798

查看方法調用棧

# 方法調用棧
stack org.slf4j.Logger warn params[1].indexOf('roadblockindex.bin')>-1 -x 3 -n 2

arthas 調用類的靜態方法

方法就是使用 ognl 表達式即可:

ognl -c 31cefde0 '@com.kwok.schedule.task.ESHisIndexParseTask@parse()'

問題來了, 這個 31cefde0 是個什么東東?

這個就是類加載器的 hashcode, 而這個類加載器就是加載我們執行的靜態方法的類的類加載器, 窩草, 有點繞口.

那么如何獲取這個類加載器的 hashcode 呢?

方式一: sc 命令

sc -d com.kwok.schedule.task.ESHisIndexParseTask

方式二: sm 命令

sm -d com.kwok.schedule.task.ESHisIndexParseTask parse

上面兩個命令輸出的 classLoaderHash 就是我們要獲取的值.

問題來了: 如何這個類沒有被加載怎么辦?

如果返回信息:Affect(row-cnt:0), 則表示該類還未執行加載, 需要使用 classloader 命令加載該類后執行該類靜態方法.

由於 SpringBoot 項目 Jar 包 ClassLoader 為 org.springframework.boot.loader.LaunchedURLClassLoader, 而 Arthas 默認的是 SystemClassLoader, 在使用 Arthas 中 ognl 命令時需要指定加載目標類的 ClassLoader.

在加載器列表中找到 org.springframework.boot.loader.LaunchedURLClassLoader 加載器的 hash.

classloader -l

使用 SpringBoot 類加載器加載目標類.

classloader -c 31cefde0 --load com.kwok.schedule.task.ESHisIndexParseTask

31cefde0 就是類加載的 hash.

這一小節的內容來自:https://blog.csdn.net/guokexiaohao/article/details/106065284

Arthas 監聽輸入參數是否包含某一字符串

監聽 com.demo.cloud.jpa.util.JPAUtil 類中的 executeNativeQuery 方法,ognl 條件參數: 只檢測包含 base_point 字符串的輸入

watch com.demo.cloud.jpa.util.JPAUtil executeNativeQuery {params} params[0].indexOf(\'base_point\')>-1 -x 3`
tt -t cn.com.xxx.base.tools.RedisUtils getStringValue  params[0].indexOf('cfg:VIDEO_CALL_RONGYUN_SERVER_ADDRESS')>-1 -x 3 -n 100

'xxx:cfg:VIDEO_CALL_RONGYUN_SERVER_ADDRESS'

參考

我的個人博客:我心永恆
原文地址:arthas 使用總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM