您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關Arthas在線java進程診斷工具怎么用,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
`Arthas` 是 Alibaba 開源的Java診斷工具,深受開發者喜愛。
當你遇到以下類似問題而束手無策時,`Arthas`可以幫助你解決:
1. 這個類從哪個 jar 包加載的?為什么會報各種類相關的 Exception?
2. 我改的代碼為什么沒有執行到?難道是我沒 commit?分支搞錯了?
3. 遇到問題無法在線上 debug,難道只能通過加日志再重新發布嗎?
4. 線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!
5. 是否有一個全局視角來查看系統的運行狀況?
6. 有什么辦法可以監控到JVM的實時運行狀態?
7. 怎么快速定位應用的熱點,生成火焰圖?
8. 怎樣直接從JVM內查找某個類的實例?
`Arthas`支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同時提供豐富的 `Tab` 自動補全功能,進一步方便進行問題的定位和診斷。
Arthas (阿爾薩斯)
Arthas
是 Alibaba 開源的Java診斷工具,深受開發者喜愛。
官網文檔:https://arthas.aliyun.com/doc/
當你遇到以下類似問題而束手無策時,Arthas
可以幫助你解決:
這個類從哪個 jar 包加載的?為什么會報各種類相關的 Exception?我改的代碼為什么沒有執行到?難道是我沒 commit?分支搞錯了?遇到問題無法在線上 debug,難道只能通過加日志再重新發布嗎?線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!是否有一個全局視角來查看系統的運行狀況?有什么辦法可以監控到JVM的實時運行狀態?怎么快速定位應用的熱點,生成火焰圖?怎樣直接從JVM內查找某個類的實例?
Arthas
支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同時提供豐富的 Tab
自動補全功能,進一步方便進行問題的定位和診斷。
下載arthas-boot.jar
,然后用java -jar
的方式啟動:
curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar
打印幫助信息:
java -jar arthas-boot.jar -h
如果下載速度比較慢,可以使用aliyun的鏡像:
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
使用as.sh
方式安裝
Arthas 支持在 Linux/Unix/Mac 等平臺上一鍵安裝,請復制以下內容,并粘貼到命令行中,敲 回車
執行即可:
curl -L https://arthas.aliyun.com/install.sh | sh
上述命令會下載啟動腳本文件 as.sh
到當前目錄,你可以放在任何地方或將其加入到 $PATH
中。
直接在shell下面執行./as.sh
,就會進入交互界面。
也可以執行./as.sh -h
來獲取更多參數信息。
全量安裝 (線上環境無外網訪問權限)
# java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.5.3
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 24438 org.elasticsearch.bootstrap.Elasticsearch
1
[ERROR] Can not read arthas version from: https://arthas.aliyun.com/api/latest_version
[ERROR] Can not find Arthas under local: /root/.arthas/lib and remote repo mirror: aliyun
[ERROR] Unable to download arthas from remote server, please download the full package according to wiki: https://github.com/alibaba/arthas
當使用快速安裝方式在線上環境進行連接Java服務的時候,很有可能因為線上環境無外部網絡訪問權限,導致Arthas無法獲取 arthas-core 等jar包,無法運行。
這時候就需要全量安裝Arthas包。
安裝方法 : ( 包大小13MB )
#### 獲取 arthas 全量包 curl -Lo arthas-packaging-latest-bin.zip 'https://arthas.aliyun.com/download/latest_version?mirror=aliyun' unzip -d arthas-latest-bin arthas-packaging-latest-bin.zip #### 開始運行 java -jar ahthas-boot.jar [INFO] arthas-boot version: 3.5.4 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 27878 /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar 1 [INFO] arthas home: /root [INFO] Try to attach process 27878 [INFO] Attach process 27878 success. [INFO] arthas-client connect 127.0.0.1 3658 ,---. ,------. ,--------.,--. ,--. ,---. ,---. / O \ | .--. ''--. .--'| '--' | / O \ ' .-' | .-. || '--'.' | | | .--. || .-. |`. `-. | | | || |\ \ | | | | | || | | |.-' | `--' `--'`--' '--' `--' `--' `--'`--' `--'`-----' wiki https://arthas.aliyun.com/doc tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html version 3.5.4 main_class pid 27878 time 2021-09-07 19:31:47
通過 rpm/deb 來安裝
這部分見官方文檔.
arthas
需要使用到 jps 命令,所以要保證 openjdk-devel
包已經安裝。
jps || yum -y install java-1.8.0-openjdk-devel
運行 arthas:
# java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.5.3
[INFO] Process 5201 already using port 3658
[INFO] Process 5201 already using port 8563
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 5201 cloud-access-auth-1.18.1.jar
[2]: 14419 tsf-stack-base-1.0.0.jar
[3]: 27862 cloud-access-gateway-1.18.1.jar
[4]: 6550 tsfmanager-operation-1.29.1.jar
提示1:當 arthas 給出的進程列表不能確定進程信息的時候,我們可以通過在命令行輸入jps -lmv
查看詳細的 java 進程信息,來確定我們要查看的 java 進程號。
提示2:當提示如下信息時:
Arthas script version: 3.0.4
Calculating attach execution time...
Attaching to 24110 using version 3.0.4...
Start arthas failed, exception stack trace:
java.lang.InternalError: instrument library is missing in target VM
at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:105)
at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:84)
at com.taobao.arthas.core.Arthas.<init>(Arthas.java:25)
at com.taobao.arthas.core.Arthas.main(Arthas.java:96)
Caused by: com.sun.tools.attach.AgentLoadException: Failed to load agent library
at sun.tools.attach.LinuxVirtualMachine.execute(LinuxVirtualMachine.java:224)
at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:58)
at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:79)
at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:103)
... 3 more
attach to target jvm (24110) failed, check /root/logs/arthas/arthas.log or stderr of target jvm for any exceptions.
我們需要重新啟動一下該進程,然后再運行 arthas ,連接到后臺 java 進程即可。
下面的 java 進程編號即當前主機已經運行的 java 服務,輸入編號即可進入 arthas 的交互式界面。
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 5201 cloud-access-auth-1.18.1.jar [2]: 14419 tsf-stack-base-1.0.0.jar [3]: 27862 cloud-access-gateway-1.18.1.jar [4]: 6550 tsfmanager-operation-1.29.1.jar 1 [INFO] local lastest version: 3.5.3, remote lastest version: 3.5.4, try to download from remote. [INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/3.5.4?mirror=aliyun [INFO] Download arthas success. [INFO] arthas home: /root/.arthas/lib/3.5.4/arthas [INFO] The target process already listen port 3658, skip attach. [INFO] arthas-client connect 127.0.0.1 3658 ,---. ,------. ,--------.,--. ,--. ,---. ,---. / O \ | .--. ''--. .--'| '--' | / O \ ' .-' | .-. || '--'.' | | | .--. || .-. |`. `-. | | | || |\ \ | | | | | || | | |.-' | `--' `--'`--' '--' `--' `--' `--'`--' `--'`-----' wiki https://arthas.aliyun.com/doc tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html version 3.5.3 main_class pid 5201 time 2021-09-03 09:55:42 [arthas@5201]$
當出現上述彩條 ARTHAS 字符提示的時候,就表示已經正常連接到指定的 Java 進程,隨即進入到下面的 arthas@PID
命令提示符。
dashboard 指令 -- 總覽JVM信息
在 arthas 命令提示符下鍵入dashboard
回車,會展示當前進程的信息,按q
退出。
dashboard 會實時輸出該java進程的JVM信息,包括線程、進程、內存、堆棧、以及當前系統運行時信息。
[arthas@5201]$ dashboard -h USAGE: dashboard [-h] [-i <value>] [-n <value>] SUMMARY: Overview of target jvm's thread, memory, gc, vm, tomcat info. EXAMPLES: dashboard dashboard -n 10 dashboard -i 2000 WIKI: https://arthas.aliyun.com/doc/dashboard OPTIONS: -h, --help this help -i, --interval <value> The interval (in ms) between two executions, default is 5000 ms. -n, --number-of-execution <value> The number of times this command will be executed.
該指令用以列出所有 arthas 交互式界面支持的 子命令 列表。
[arthas@5201]$ help NAME DESCRIPTION help Display Arthas Help auth Authenticates the current session keymap Display all the available keymap for the specified connection. sc Search all the classes loaded by JVM sm Search the method of classes loaded by JVM classloader Show classloader info jad Decompile class getstatic Show the static field of a class monitor Monitor method execution statistics, e.g. total/success/failure count, average rt, fail rate, etc. stack Display the stack trace for the specified class and method thread Display thread info, thread stack trace Trace the execution time of specified method invocation. watch Display the input/output parameter, return object, and thrown exception of specified method invocation tt Time Tunnel jvm Display the target JVM information perfcounter Display the perf counter information. ognl Execute ognl expression. mc Memory compiler, compiles java files into bytecode and class files in memory. redefine Redefine classes. @see Instrumentation#redefineClasses(ClassDefinition...) retransform Retransform classes. @see Instrumentation#retransformClasses(Class...) dashboard Overview of target jvm's thread, memory, gc, vm, tomcat info. dump Dump class byte array from JVM heapdump Heap dump options View and change various Arthas options cls Clear the screen reset Reset all the enhanced classes version Display Arthas version session Display current session information sysprop Display, and change the system properties. sysenv Display the system env. vmoption Display, and update the vm diagnostic options. logger Print logger info, and update the logger level history Display command history cat Concatenate and print files base64 Encode and decode using Base64 representation echo write arguments to the standard output pwd Return working directory name mbean Display the mbean information grep grep command for pipes. tee tee command for pipes. profiler Async Profiler. https://github.com/jvm-profiling-tools/async-profiler vmtool jvm tool stop Stop/Shutdown Arthas server and exit the console.
每個子命令,都可以跟上 -h
來進一步獲取幫助用法信息。
[arthas@5201]$ thread -h USAGE: thread [--all] [-h] [-b] [--lockedMonitors] [--lockedSynchronizers] [-i <value>] [--state <value>] [-n <value>] [id] SUMMARY: Display thread info, thread stack EXAMPLES: thread thread 51 thread -n -1 thread -n 5 thread -b thread -i 2000 thread --state BLOCKED WIKI: https://arthas.aliyun.com/doc/thread OPTIONS: --all Display all thread results instead of the first page -h, --help this help -b, --include-blocking-thread Find the thread who is holding a lock that blocks the most number of threads. --lockedMonitors Find the thread info with lockedMonitors flag, default value is false. --lockedSynchronizers Find the thread info with lockedSynchronizers flag, default value is false. -i, --sample-interval <value> Specify the sampling interval (in ms) when calculating cpu usage. --state <value> Display the thead filter by the state. NEW, RUNNABLE, TIMED_WAITING, WAITING, BLOCKED, TERMINATED is optional. -n, --top-n-threads <value> The number of thread(s) to show, ordered by cpu utilization, -1 to show all. <id> Show thread stack
$ thread -i 5000 ## 獲取時間跨度為5s的計算匯總數據 $ thread -n 3 ## 根據 CPU 使用率排序,獲取從高到低的 3 個線程堆棧信息 $ thread -b ## 僅查看死鎖線程的堆棧信息 $ thread --lockedSynchronizers ## 僅查看同步器死鎖的線程堆棧信息
stop
: 停止和退出 Arthas consol ,正常退出步驟。
exit
: 僅離開 Arthas consol,但是綁定到 Java 進程的 arthas 任務不會退出。
[SHELL]# java -jar arthas-boot.jar [INFO] arthas-boot version: 3.5.3 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 5201 cloud-access-auth-1.18.1.jar [2]: 14419 tsf-stack-base-1.0.0.jar [3]: 27862 cloud-access-gateway-1.18.1.jar [4]: 6550 tsfmanager-operation-1.29.1.jar 1 [INFO] arthas home: /root/.arthas/lib/3.5.4/arthas [INFO] Try to attach process 5201 [INFO] Attach process 5201 success. [INFO] arthas-client connect 127.0.0.1 3658 ,---. ,------. ,--------.,--. ,--. ,---. ,---. / O \ | .--. ''--. .--'| '--' | / O \ ' .-' | .-. || '--'.' | | | .--. || .-. |`. `-. | | | || |\ \ | | | | | || | | |.-' | `--' `--'`--' '--' `--' `--' `--'`--' `--'`-----' wiki https://arthas.aliyun.com/doc tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html version 3.5.4 main_class pid 5201 time 2021-09-03 13:05:51 [arthas@5201]$ exit [SHELL]# java -jar arthas-boot.jar [INFO] arthas-boot version: 3.5.3 [INFO] Process 5201 already using port 3658 ## 由于上次并沒有 shutdown 關閉arthas與java進程的綁定,所以Arthas重新啟動的時候,檢測到仍然綁定到 5201 進程上面的。 [INFO] Process 5201 already using port 8563 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 5201 cloud-access-auth-1.18.1.jar [2]: 14419 tsf-stack-base-1.0.0.jar [3]: 27862 cloud-access-gateway-1.18.1.jar [4]: 6550 tsfmanager-operation-1.29.1.jar
我們通過 jstack -l 5201 來證實這一點
[root@VM-0-4-centos ~]# jstack -l 5201 | more 2021-09-03 13:08:16 Full thread dump OpenJDK 64-Bit Server VM (25.302-b08 mixed mode): "arthas-NettyHttpTelnetBootstrap-3-3" #169 daemon prio=5 os_prio=0 tid=0x00007f314000b800 nid=0x5632 runnable [0x00007f30cb51a000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x00000000e8cafb00> (a com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x00000000e8caf8a8> (a java.util.Collections$UnmodifiableSet) - locked <0x00000000e8caf790> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101) at com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68) at com.alibaba.arthas.deps.io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:810) at com.alibaba.arthas.deps.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:457) at com.alibaba.arthas.deps.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) at com.alibaba.arthas.deps.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at com.alibaba.arthas.deps.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - None "arthas-NettyHttpTelnetBootstrap-3-2" #168 daemon prio=5 os_prio=0 tid=0x00007f314000a000 nid=0x51ce runnable [0x00007f30d09f9000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x00000000e8cac058> (a com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x00000000e8cabe00> (a java.util.Collections$UnmodifiableSet) - locked <0x00000000e8cabce8> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101) at com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68)
我們可以看到 5201 進程的java堆棧信息,有 arthas 的線程正在運行中。
正常退出步驟:
[arthas@5201]$ stop Resetting all enhanced classes ... Affect(class count: 0 , method count: 0) cost in 0 ms, listenerId: 0 Arthas Server is going to shutdown... [arthas@5201]$ session (f0151617-7fd2-4b4b-b79f-31d366a72fc5) is closed because server is going to shutdown. [SHELL]# jstack -l 5201 | more 2021-09-03 13:10:16 Full thread dump OpenJDK 64-Bit Server VM (25.302-b08 mixed mode): "Abandoned connection cleanup thread" #51 daemon prio=5 os_prio=0 tid=0x00007f30e0246000 nid=0x1d86 in Object.wait() [0x00007f3120393000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) - locked <0x00000000e3280300> (a java.lang.ref.ReferenceQueue$Lock) at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:64) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - <0x00000000e3280390> (a java.util.concurrent.ThreadPoolExecutor$Worker) "Tomcat JDBC Pool Cleaner[1450495309:1630634377161]" #50 daemon prio=5 os_prio=0 tid=0x00007f30e01e4800 nid=0x1d85 in Object.wait() [0x00007f3120494000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.util.TimerThread.mainLoop(Timer.java:552) - locked <0x00000000e3280540> (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505) Locked ownable synchronizers: - None
可以看到,使用 stop
指令關閉arthas診斷程序后,java 進程上面的arthas線程綁定也一并退出了。
watch
指令算是 Arthas 中最常用的指令之一了,它能夠獲取指定包.類.方法
的入參
、自身類方法體內部對象
以及返回對象值
。
[arthas@5201]$ watch -h USAGE: watch [-b] [-e] [--exclude-class-pattern <value>] [-x <value>] [-f] [-h] [-n <value>] [--listenerId <value>] [-E] [-M <value>] [-s] [-v] class-pattern method-pattern [express] [condition-express] SUMMARY: Display the input/output parameter, return object, and thrown exception of specified method invocation The express may be one of the following expression (evaluated dynamically): target : the object clazz : the object's class method : the constructor or method params : the parameters array of method params[0..n] : the element of parameters array returnObj : the returned object of method throwExp : the throw exception of method isReturn : the method ended by return isThrow : the method ended by throwing exception #cost : the execution time in ms of method invocation Examples: watch org.apache.commons.lang.StringUtils isBlank watch org.apache.commons.lang.StringUtils isBlank '{params, target, returnObj, throwExp}' -x 2 watch *StringUtils isBlank params[0] params[0].length==1 watch *StringUtils isBlank params '#cost>100' watch -f *StringUtils isBlank params watch *StringUtils isBlank params[0] watch -E -b org\.apache\.commons\.lang\.StringUtils isBlank params[0] watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter WIKI: https://arthas.aliyun.com/doc/watch OPTIONS: -b, --before Watch before invocation -e, --exception Watch after throw exception --exclude-class-pattern <value> exclude class name pattern, use either '.' or '/' as separator -x, --expand <value> Expand level of object (1 by default) -f, --finish Watch after invocation, enable by default -h, --help this help -n, --limits <value> Threshold of execution times --listenerId <value> The special listenerId -E, --regex Enable regular expression to match (wildcard matching by default) -M, --sizeLimit <value> Upper size limit in bytes for the result (10 * 1024 * 1024 by default) -s, --success Watch after successful invocation -v, --verbose Enables print verbose information, default value false. <class-pattern> The full qualified class name you want to watch <method-pattern> The method name you want to watch <express> The content you want to watch, written by ognl. Default value is '{params, target, returnObj}' Examples: params params[0] 'params[0]+params[1]' '{params[0], target, returnObj}' returnObj throwExp target clazz method <condition-express> Conditional expression in ognl style, for example: TRUE : 1==1 TRUE : true FALSE : false TRUE : 'params.length>=0' FALSE : 1==2 '#cost>100'
參數說明
參數名稱 | 參數說明 |
---|---|
class-pattern | 類名表達式匹配 |
method-pattern | 方法名表達式匹配 |
express | 觀察表達式,默認值:{params, target, returnObj} |
condition-express | 條件表達式 |
[b] | 在方法調用之前觀察 |
[e] | 在方法異常之后觀察 |
[s] | 在方法返回之后觀察 |
[f] | 在方法結束之后(正常返回和異常返回)觀察 |
[E] | 開啟正則表達式匹配,默認為通配符匹配 |
[x:] | 指定輸出結果的屬性遍歷深度,默認為 1 |
這里重點要說明的是觀察表達式,觀察表達式的構成主要由 #OGNL
表達式組成,所以你可以這樣寫"{params,returnObj}"
,只要是一個合法的 ognl 表達式,都能被正常支持。
觀察的維度也比較多,主要體現在參數 advice
的數據結構上。Advice
參數最主要是封裝了通知節點的所有信息。請參考表達式核心變量中關于該節點的描述。
使用舉例:
我需要觀察cloud-access-auth-1.18.1.jar
進程在處理登錄信息時的登錄方法信息,日志如下:
13:42:54.205 INFO [http-nio-7001-exec-4] c.t.c.access.sso.service.impl.AuthenticateService - [Access Auth] account login parameter. accountName:qcloudAdmin ,password:******
得到指定類名為AuthenticateService
。
我們帶到 Arthas 中進行 watch:
### 報名在日志文件中是簡寫,所以我這里使用通配符方式匹配類名,第二個參數方法名我也用*代替,全部匹配 [arthas@5201]$ watch *AuthenticateService * Press Q or Ctrl+C to abort. Affect(class count: 2 , method count: 6) cost in 130 ms, listenerId: 16 ### 從輸出信息得知,在這個 Java 進程所有代碼中匹配到有兩個類,一共6個方法
我們來點擊頁面登錄按鈕,看看 watch 中能觀察到哪些動作:
[arthas@5201]$ watch *AuthenticateService * Press Q or Ctrl+C to abort. Affect(class count: 2 , method count: 6) cost in 130 ms, listenerId: 16 #### 第一個方法開始執行 Begin method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 13:51:25; [cost=2.217281ms] result=@ArrayList[ @Object[][isEmpty=false;size=3], @AuthenticateService[com.tencent.cloud.access.sso.service.impl.AuthenticateService@f5cadbf], @AccessAuthPrincipal[com.tencent.cloud.access.sso.model.AccessAuthPrincipal@72f71bf6], ] #### 第一個方法執行結束 End #### 第二個方法開始執行 Begin method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.updateSession location=AtExit ts=2021-09-03 13:51:25; [cost=0.956478ms] result=@ArrayList[ @Object[][isEmpty=false;size=2], @AuthenticateService[com.tencent.cloud.access.sso.service.impl.AuthenticateService@f5cadbf], @AuthenticationResponse[com.tencent.cloud.access.sso.model.AuthenticationResponse@6b2bae10], ] #### 第二個方法執行退出 End ..............
在輸出信息中我們可以看到,第一行有完整的方法路徑
,以及獲取的退出狀態location
。
AtExit:表示正常退出。
AtExceptionExit:表示異常退出。
第二行有方法執行的開始時間戳
以及cost 開銷
,最后一個為watch的結果。
這里result
的 ArrayList 數組是 watch
指令的強大之處,它默認包含三個對象:
params
: 入參,通常為數組,這里為 @Object
對象
target
: 運行中當前 this 對象,也就是這個類對象本身,這里為@AuthenticateService
實體類對象
returnObj
: 返回對象值,這里為返回的@AccessAuthPrincipal
對象
我們重新執行一次 watch 指令,這次咱們精確指定類名和方法名,以及加一個-x
解析深度參數:
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login -x 2 Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 2) cost in 74 ms, listenerId: 17 method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 14:10:15; [cost=3.289679ms] result=@ArrayList[ @Object[][ @String[qcloudAdmin], @String[Bgi8c0yC+IAvRLkuQRy6kLQ6T2J/9PNrL6G/+KX9ppE=], @String[127.0.0.1], ], @AuthenticateService[ log=@Logger[Logger[com.tencent.cloud.access.sso.service.impl.AuthenticateService]], sessionDAO=@RedisSessionDAO[com.tencent.cloud.access.sso.shiro.RedisSessionDAO@61813e98], accountSessionService=@AccountSessionService[com.tencent.cloud.access.account.service.impl.AccountSessionService@30e815ac], accessAuthRealm=@AccessAuthRealm[com.tencent.cloud.access.sso.shiro.AccessAuthRealm@1faea5], accountService=@AccountService[com.tencent.cloud.access.account.service.impl.AccountService@197459d8], ssoProperties=@SsoProperties[com.tencent.cloud.access.sso.config.SsoProperties@461879b2], securityManager=@DefaultSecurityManager[org.apache.shiro.mgt.DefaultSecurityManager@3b0f92f0], ssoService=@QCloudSsoService[com.tencent.cloud.access.sso.service.impl.QCloudSsoService@4f8704f5], userService=@UserService[com.tencent.cloud.access.user.service.impl.UserService@5e69da74], ], @AccessAuthPrincipal[ serialVersionUID=@Long[-2856270666386831504], accountName=@String[qcloudAdmin], userId=null, accountId=@String[account-96a79v5b], password=@String[VYUQeJrC5EJq21t/f9rb1Djm+4+eanqXY3ZkW2oiiwA=], serviceCode=null, isAdmin=null, loginName=null, serialVersionUID=@Long[8229738167949958388], token=@String[54158a08d8104de57a855249eb6ffe06], serialVersionUID=@Long[-4556824360581761962], appId=null, subAccountUin=null, uin=null, requestId=null, region=null, kv=null, ], ] method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 14:10:15; [cost=9.571541ms] result=@ArrayList[ @Object[][ @LoginRequest[com.tencent.cloud.access.sso.model.LoginRequest@3dd2bbb0], ], @AuthenticateService[ log=@Logger[Logger[com.tencent.cloud.access.sso.service.impl.AuthenticateService]], sessionDAO=@RedisSessionDAO[com.tencent.cloud.access.sso.shiro.RedisSessionDAO@61813e98], accountSessionService=@AccountSessionService[com.tencent.cloud.access.account.service.impl.AccountSessionService@30e815ac], accessAuthRealm=@AccessAuthRealm[com.tencent.cloud.access.sso.shiro.AccessAuthRealm@1faea5], accountService=@AccountService[com.tencent.cloud.access.account.service.impl.AccountService@197459d8], ssoProperties=@SsoProperties[com.tencent.cloud.access.sso.config.SsoProperties@461879b2], securityManager=@DefaultSecurityManager[org.apache.shiro.mgt.DefaultSecurityManager@3b0f92f0], ssoService=@QCloudSsoService[com.tencent.cloud.access.sso.service.impl.QCloudSsoService@4f8704f5], userService=@UserService[com.tencent.cloud.access.user.service.impl.UserService@5e69da74], ], @AuthenticationResponse[ serialVersionUID=@Long[-6134589862066278677], token=@String[54158a08d8104de57a855249eb6ffe06], accountId=@String[account-96a79v5b], changePwd=@String[N], users=@ArrayList[isEmpty=false;size=1], ], ] ..............
watch
指令的-x
選項表示解析三個階段的對象深度,默認值為 1,也就是只解析到對象層,不解析對象的下一級屬性等信息。
通過上述指令,我們獲取到了更加詳細的入參、this對象、返回值的信息,依次解析如下:
params 方法入參:
@String[qcloudAdmin]: 參數一,用戶名
@String[Bgi8c0yC+IAvRLkuQRy6kLQ6T2J/9PNrL6G/+KX9ppE=]: 密碼加密串
@String[127.0.0.1]: 來源主機信息
this
方法體內部對象:
log=@Logger: 定義 Logger 對象
sessionDAO=@RedisSessionDAO: 會話session數據入口,為 RedisSessionDAO 對象
accountSessionService=@AccountSessionService: 私有對象........
returnObj
返回值對象,這里為@AccessAuthPrincipal
對象:
serialVersionUID: 用戶
UIDaccountName: 登錄用戶名
password: 用戶密碼加密串token: token串
........
條件表達式過濾
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login '{params[0]=qcloudAdmin,returnObj}' -x 2
診斷返回信息包含params[0]
和returnObj對象
,而且僅獲取入參params[0] == "qcloudAdmin"
的方法調用,最后解析深度為 2。
只有滿足條件的調用,才會被 Arthas 捕獲到。
觀察異常信息
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login '{params[0],throwExp}' -e -x 2
-e: 表示在拋出異常之后觀察
express觀察表達式第二個參數throwExp
: 表示異常信息的變量是throwExp
按方法執行耗時進行過濾
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login '{params[0],returnObj}' '#cost>200' -x 2
watch
指令的第四個參數 condition-express 為#cost>200
,表示診斷處理耗時大于 200ms 才會被捕獲輸出。
-x 2
: 解析深度為 2。
僅觀察當前對象的屬性
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login 'target' -x 3 Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 2) cost in 76 ms, listenerId: 23 method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 14:48:33; [cost=3.189525ms] result=@AuthenticateService[ log=@Logger[ serialVersionUID=@Long[5454405123156820674], FQCN=@String[ch.qos.logback.classic.Logger], name=@String[com.tencent.cloud.access.sso.service.impl.AuthenticateService], level=null, effectiveLevelInt=@Integer[20000], parent=@Logger[ serialVersionUID=@Long[5454405123156820674], FQCN=@String[ch.qos.logback.classic.Logger], name=@String[com.tencent.cloud.access.sso.service.impl], level=null, effectiveLevelInt=@Integer[20000], parent=@Logger[Logger[com.tencent.cloud.access.sso.service]], childrenList=@CopyOnWriteArrayList[isEmpty=false;size=2], aai=null, additive=@Boolean[true], loggerContext=@LoggerContext[ch.qos.logback.classic.LoggerContext[default]], ], childrenList=null, aai=null, additive=@Boolean[true], loggerContext=@LoggerContext[ DEFAULT_PACKAGING_DATA=@Boolean[false], root=@Logger[Logger[ROOT]], size=@Integer[501], noAppenderWarning=@Integer[0], loggerContextListenerList=@ArrayList[isEmpty=false;size=1], loggerCache=@ConcurrentHashMap[isEmpty=false;size=501], loggerContextRemoteView=@LoggerContextVO[LoggerContextVO{name='default', propertyMap={}, birthTime=1630634095948}], turboFilterList=@TurboFilterList[isEmpty=true;size=0], packagingDataEnabled=@Boolean[false], maxCallerDataDepth=@Integer[8], resetCount=@Integer[2], frameworkPackages=@ArrayList[isEmpty=true;size=0], birthTime=@Long[1630634095948], name=@String[default], sm=@BasicStatusManager[ch.qos.logback.core.BasicStatusManager@612c57fb], propertyMap=@HashMap[isEmpty=true;size=0], objectMap=@HashMap[isEmpty=false;size=6], configurationLock=@LogbackLock[ch.qos.logback.core.spi.LogbackLock@36566db5], scheduledExecutorService=null, scheduledFutures=@ArrayList[isEmpty=true;size=0], lifeCycleManager=@LifeCycleManager[ch.qos.logback.core.LifeCycleManager@44477e6], started=@Boolean[false], ], ], sessionDAO=@RedisSessionDAO[ .............
擴展思維,我們可以直接透過一次調用,觀察到底層連接 jdbc 的信息:
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login 'target.userService.userDao.jdbcTemplate.dataSource.pool.poolProperties.url' -x 2
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 2) cost in 69 ms, listenerId: 34
method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit
ts=2021-09-03 15:09:55; [cost=2.682966ms] result=@String[jdbc:mysql://*.*.*.*:3306/access_auth?useSSL=false&characterEncoding=utf8]
method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit
ts=2021-09-03 15:09:55; [cost=21.373065ms] result=@String[jdbc:mysql://*.*.*.*:3306/access_auth?useSSL=false&characterEncoding=utf8]
這里就從頂層往下,獲取到了該次調用,涉及到查庫的 jdbc dataSource
連接配置信息。
result
返回的是一個 String
類型對象,值為 jdbc:mysql://*.*.*.*:3306/access_auth?useSSL=false&characterEncoding=utf8
。
排除指定的類
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.* * 'target' -x 1 --exclude-class-pattern AuthorizeService | grep --color AuthorizeService Press Q or Ctrl+C to abort.
--exclude-class-pattern
:排除指定的類
方法內部調用路徑,并輸出方法路徑上的每個節點上耗時
trace
命令能主動搜索 class-pattern
/method-pattern
對應的方法調用路徑,渲染和統計整個調用鏈路上的所有性能開銷和追蹤調用鏈路
參數說明
參數名稱 | 參數說明 |
---|---|
class-pattern | 類名表達式匹配 |
method-pattern | 方法名表達式匹配 |
condition-express | 條件表達式 |
[E] | 開啟正則表達式匹配,默認為通配符匹配 |
[n:] | 命令執行次數 |
#cost | 方法執行耗時 |
這里重點要說明的是觀察表達式,觀察表達式的構成主要由 #OGNL
表達式組成,所以你可以這樣寫"{params,returnObj}"
,只要是一個合法的 ognl 表達式,都能被正常支持。
觀察的維度也比較多,主要體現在參數 advice
的數據結構上。Advice
參數最主要是封裝了通知節點的所有信息。
請參考表達式核心變量中關于該節點的描述。
特殊用法請參考:https://github.com/alibaba/arthas/issues/71
OGNL表達式官網:https://commons.apache.org/proper/commons-ognl/language-guide.html
很多時候我們只想看到某個方法的rt大于某個時間之后的trace結果,現在Arthas可以按照方法執行的耗時來進行過濾了,例如trace *StringUtils isBlank '#cost>100'
表示當執行時間超過100ms的時候,才會輸出trace的結果。
watch/stack/trace這個三個命令都支持#cost
使用舉例:
[arthas@5201]$ trace com.tencent.cloud.access.sso.service.impl.AuthenticateService login Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 2) cost in 114 ms, listenerId: 49 `---ts=2021-09-03 15:37:52;thread_name=http-nio-7001-exec-5;id=18;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@1cfd053 `---[6.69059ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:login() +---[0.045058ms] com.tencent.cloud.access.sso.model.LoginRequest:getOpt() #87 +---[0.011503ms] com.tencent.cloud.access.sso.constant.LoginType:getType() #88 +---[0.004858ms] com.tencent.cloud.access.sso.constant.LoginType:getType() #89 +---[0.005082ms] com.tencent.cloud.access.sso.model.LoginRequest:getAccountName() #93 +---[0.005074ms] com.tencent.cloud.access.sso.model.LoginRequest:getPassword() #94 +---[min=0.002257ms,max=0.010395ms,total=0.012652ms,count=2] org.springframework.util.StringUtils:isEmpty() #95 +---[0.008128ms] com.tencent.cloud.access.sso.config.SsoProperties:isPasswordTextPrintable() #100 +---[0.084201ms] org.slf4j.Logger:info() #99 +---[0.00653ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:<init>() #101 +---[0.004871ms] com.tencent.cloud.access.sso.model.LoginRequest:getRemoteHost() #102 +---[3.317607ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:login() #102 | `---[3.285177ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:login() | +---[0.008045ms] org.apache.shiro.authc.UsernamePasswordToken:<init>() #139 | +---[0.011232ms] org.apache.shiro.subject.SimplePrincipalCollection:<init>() #141 | +---[0.00843ms] org.apache.shiro.subject.support.DelegatingSubject:<init>() #142 | +---[0.015667ms] org.apache.shiro.util.ThreadContext:bind() #143 | +---[1.051658ms] org.apache.shiro.subject.support.DelegatingSubject:login() #144 | +---[0.988623ms] org.apache.shiro.subject.support.DelegatingSubject:getSession() #145 | +---[0.015629ms] org.apache.shiro.session.Session:getId() #146 | +---[0.323618ms] org.apache.shiro.subject.support.DelegatingSubject:getPrincipal() #147 | +---[0.009258ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:setToken() #149 | +---[0.007608ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:setAccountName() #150 | +---[0.429798ms] org.apache.shiro.session.Session:setAttribute() #151 | `---[0.207347ms] com.tencent.cloud.access.account.service.IAccountSessionService:bind() #152 +---[0.010654ms] com.tencent.cloud.access.account.Account:<init>() #103 +---[0.824315ms] com.tencent.cloud.access.account.service.IAccountService:find() #103 +---[0.006474ms] com.tencent.cloud.access.account.Account:getLock() #104 +---[0.004144ms] com.tencent.cloud.access.account.Account:getChangePassword() #107 +---[0.005663ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:setChangePwd() #107 +---[0.004683ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:getToken() #108 +---[0.00414ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:setToken() #108 +---[0.003733ms] com.tencent.cloud.access.account.Account:getAccountId() #109 +---[0.005164ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:setAccountId() #109 +---[0.002866ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:setAccountName() #110 +---[0.00399ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:getAccountId() #112 +---[0.014922ms] com.tencent.cloud.access.user.User:<init>() #112 +---[0.004781ms] com.tencent.cloud.access.user.User:setAppIsolate() #113 +---[0.83272ms] com.tencent.cloud.access.user.service.IUserService:findAccountList() #114 +---[0.006398ms] com.tencent.cloud.access.user.User:getUserId() #116 +---[0.005214ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:setUserId() #116 +---[0.00349ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:getToken() #118 +---[0.002987ms] com.tencent.cloud.access.user.User:getUserId() #118 +---[0.887095ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:updateSession() #118 `---[0.004734ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:setUsers() #120 `---ts=2021-09-03 15:37:52;thread_name=http-nio-7001-exec-1;id=14;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@1cfd053 `---[1.28437ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:login() +---[0.003596ms] com.tencent.cloud.access.sso.model.LoginRequest:getOpt() #87 +---[0.006076ms] com.tencent.cloud.access.sso.constant.LoginType:getType() #88 +---[0.002865ms] com.tencent.cloud.access.sso.constant.LoginType:getType() #89 +---[0.010558ms] com.tencent.cloud.access.sso.model.LoginRequest:getAccessToken() #123 +---[0.003959ms] com.tencent.cloud.access.sso.model.LoginRequest:getUid() #124 +---[0.003368ms] org.springframework.util.StringUtils:isEmpty() #125 +---[0.002671ms] org.springframework.util.StringUtils:isEmpty() #128 `---[1.166953ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:updateSession() #131
耗時過濾診斷
[arthas@5201]$ trace com.tencent.cloud.access.sso.service.impl.AuthenticateService login '#cost > 2000'
#cost > 2000
: 僅捕獲開銷時間大于 2000ms 的路徑。
僅過濾方法一次調用
[arthas@5201]$ trace com.tencent.cloud.access.sso.service.impl.AuthenticateService login -n 1
僅捕獲一次指定方法的調用,然后退出任務。
sysprop 指令 -- 獲取/設置進程系統屬性
sysprop 主要用來查看、設置當前進程的系統屬性信息。
使用舉例
查看當前java進程的系統屬性
[arthas@27878]$ sysprop KEY VALUE ------------------------------------------------------------------------- awt.toolkit sun.awt.X11.XToolkit file.encoding.pkg sun.io java.specification.version 1.8 sun.cpu.isalist sun.jnu.encoding UTF-8 java.class.path /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar java.vm.vendor Tencent sun.arch.data.model 64 java.vendor.url http://jdk.oa.com/ catalina.useNaming false user.timezone Asia/Shanghai org.jboss.logging.provider slf4j os.name Linux java.vm.specification.version 1.8 @appId tsf-ratelimit user.country US sun.java.launcher SUN_STANDARD sun.boot.library.path /data/TencentKona-8.0.2-252/jre/lib/amd64 sun.java.command /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar sun.cpu.endian little user.home /root user.language en java.specification.vendor Oracle Corporation java.home /data/TencentKona-8.0.2-252/jre file.separator / line.separator java.vm.specification.vendor Oracle Corporation java.specification.name Java Platform API Specification java.awt.graphicsenv sun.awt.X11GraphicsEnvironment java.awt.headless true LOG_LEVEL_PATTERN %5p [bootstrap,%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}] sun.boot.class.path /data/TencentKona-8.0.2-252/jre/lib/resources.jar:/data/TencentKona-8.0.2-252/jre/lib/rt.jar:/data/TencentKona-8.0.2-252/jre/lib/sunrsasign.jar:/data/TencentKona-8.0.2-252/jre/lib/jsse.jar:/data/TencentKona-8.0.2-2 52/jre/lib/jce.jar:/data/TencentKona-8.0.2-252/jre/lib/charsets.jar:/data/TencentKona-8.0.2-252/jre/lib/jfr.jar:/data/TencentKona-8.0.2-252/jre/classes java.protocol.handler.pkgs org.springframework.boot.loader sun.management.compiler HotSpot 64-Bit Tiered Compilers java.runtime.version 1.8.0_252-b1 java.net.preferIPv4Stack true user.name root path.separator : os.version 3.10.0-1127.19.1.el7.x86_64 java.endorsed.dirs /data/TencentKona-8.0.2-252/jre/lib/endorsed java.runtime.name OpenJDK Runtime Environment file.encoding UTF-8 spring.beaninfo.ignore true sun.nio.ch.bugLevel java.vm.name OpenJDK 64-Bit Server VM LOG_FILE /var/log/tsf-oss/tsf-ratelimit/tsf-ratelimit java.vendor.url.bug http://ce.oa.com/bia java.io.tmpdir /tmp catalina.home /tmp/tomcat.8220305148167761737.23000 java.version 1.8.0_252 user.dir /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1 os.arch amd64 PID 27878 java.vm.specification.name Java Virtual Machine Specification java.awt.printerjob sun.print.PSPrinterJob sun.os.patch.level unknown catalina.base /tmp/tomcat.8220305148167761737.23000 loader.path /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/config java.library.path /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib::/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib java.vm.info mixed mode, sharing java.vendor Tencent java.vm.version 25.252-b1 java.ext.dirs /data/TencentKona-8.0.2-252/jre/lib/ext:/usr/java/packages/lib/ext sun.io.unicode.encoding UnicodeLittle java.class.version 52.0
臨時設置當前進程的系統屬性
[arthas@29749]$ sysprop java.class.path /data/jdk/latest Successfully changed the system property. KEY VALUE ----------------------------------------------------------------------------------- java.class.path /data/jdk/latest
參數說明
[arthas@29749]$ logger -h USAGE: logger [-c <value>] [--classLoaderClass <value>] [-h] [--include-no-appender] [-l <value>] [-n <value>] SUMMARY: Print logger info, and update the logger level Examples: logger logger -c 327a647b logger -c 327a647b --name ROOT --level debug logger --include-no-appender WIKI: https://arthas.aliyun.com/doc/logger OPTIONS: -c, --classloader <value> classLoader hashcode, if no value is set, default value is SystemClassLoader --classLoaderClass <value> The class name of the special class's classLoader. -h, --help this help --include-no-appender include the loggers which don't have appenders, default value false -l, --level <value> set logger level -n, --name <value> logger name
使用舉例
設置 logger 的 ROOT appender 的日志級別
##### 獲取 logger 類信息 [arthas@29749]$ logger name ROOT class ch.qos.logback.classic.Logger classLoader org.springframework.boot.loader.LaunchedURLClassLoader@5674cd4d classLoaderHash 5674cd4d level INFO effectiveLevel INFO ...................... ##### 設置 ROOT 名稱日志級別為 DEBUG [arthas@29749]$ logger -c 5674cd4d -n ROOT -l DEBUG
heapdump 指令 -- 堆轉儲
參數說明
[arthas@29749]$ heapdump -h USAGE: heapdump [-h] [-l] [file] SUMMARY: Heap dump Examples: heapdump ## hprof 文件保存到當前目錄下 heapdump --live ## 活躍對象 heapdump --live /tmp/dump.hprof WIKI: https://arthas.aliyun.com/doc/heapdump OPTIONS: -h, --help this help -l, --live Dump only live objects; if not specified, all objects in the heap are dumped. <file> Output file
參數說明
[arthas@29749]$ sc -h USAGE: sc [-c <value>] [--classLoaderClass <value>] [-d] [-x <value>] [-f] [-h] [-n <value>] [-E] class-pattern SUMMARY: Search all the classes loaded by JVM EXAMPLES: sc -d org.apache.commons.lang.StringUtils sc -d org/apache/commons/lang/StringUtils sc -d *StringUtils sc -d -f org.apache.commons.lang.StringUtils sc -E org\\.apache\\.commons\\.lang\\.StringUtils WIKI: https://arthas.aliyun.com/doc/sc OPTIONS: -c, --classloader <value> The hash code of the special class's classLoader --classLoaderClass <value> The class name of the special class's classLoader. -d, --details Display the details of class -x, --expand <value> Expand level of object (0 by default) -f, --field Display all the member variables -h, --help this help -n, --limits <value> Maximum number of matching classes with details (100 by default) -E, --regex Enable regular expression to match (wildcard matching by default) <class-pattern> Class name pattern, use either '.' or '/' as separator
使用舉例
#### 根據通配符獲取已加載的包名類名列表 [arthas@29749]$ sc com.tencent.tsf.* com.sun.proxy.$Proxy132 com.sun.proxy.$Proxy143 com.tencent.tsf.TsfApplicationStarter com.tencent.tsf.TsfApplicationStarter$$EnhancerBySpringCGLIB$$e6e6d3dc com.tencent.tsf.common.TsfBaseEntity com.tencent.tsf.common.TsfPage com.tencent.tsf.common.TsfPageQuery com.tencent.tsf.common.aop.ControllerCommonLog ..............
-d
參數獲取具體類的基礎信息:
[arthas@29749]$ sc com.tencent.tsf.TsfApplicationStarter -d class-info com.tencent.tsf.TsfApplicationStarter code-source file:/data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar!/BOOT-INF/lib/tsf-common-1.29.1.jar!/ name com.tencent.tsf.TsfApplicationStarter isInterface false isAnnotation false isEnum false isAnonymousClass false isArray false isLocalClass false isMemberClass false isPrimitive false isSynthetic false simple-name TsfApplicationStarter modifier public annotation org.springframework.boot.autoconfigure.SpringBootApplication,org.springframework.cloud.client.discovery.EnableDiscoveryClient,org.springframework.cloud.netflix.feign.EnableFeignClients,org.springframework.transaction.annotation.EnableTransactionManag ement,org.springframework.scheduling.annotation.EnableScheduling,org.springframework.context.annotation.EnableAspectJAutoProxy interfaces super-class +-java.lang.Object class-loader +-org.springframework.boot.loader.LaunchedURLClassLoader@5674cd4d +-sun.misc.Launcher$AppClassLoader@70dea4e +-sun.misc.Launcher$ExtClassLoader@65e2dbf3 classLoaderHash 5674cd4d class-info com.tencent.tsf.TsfApplicationStarter$$EnhancerBySpringCGLIB$$e6e6d3dc code-source file:/data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar!/BOOT-INF/lib/tsf-common-1.29.1.jar!/ name com.tencent.tsf.TsfApplicationStarter$$EnhancerBySpringCGLIB$$e6e6d3dc isInterface false isAnnotation false isEnum false isAnonymousClass false isArray false isLocalClass false isMemberClass false isPrimitive false isSynthetic false simple-name TsfApplicationStarter$$EnhancerBySpringCGLIB$$e6e6d3dc modifier public annotation interfaces org.springframework.context.annotation.ConfigurationClassEnhancer$EnhancedConfiguration super-class +-com.tencent.tsf.TsfApplicationStarter +-java.lang.Object class-loader +-org.springframework.boot.loader.LaunchedURLClassLoader@5674cd4d +-sun.misc.Launcher$AppClassLoader@70dea4e +-sun.misc.Launcher$ExtClassLoader@65e2dbf3 classLoaderHash 5674cd4d Affect(row-cnt:2) cost in 17 ms.
該指令參數與 sc 指令參數類似。
使用舉例:
## 獲取 com.tencent.tsf.common.TsfPageQuery 類的所有方法列表 [arthas@29749]$ sm com.tencent.tsf.common.TsfPageQuery * com.tencent.tsf.ratelimit.domain.Ratelimit <init>(Lcom/tencent/tsf/ratelimit/domain/Ratelimit;)V com.tencent.tsf.ratelimit.domain.Ratelimit <init>()V com.tencent.tsf.ratelimit.domain.Ratelimit toString()Ljava/lang/String; com.tencent.tsf.ratelimit.domain.Ratelimit getRules()Ljava/util/List; com.tencent.tsf.ratelimit.domain.Ratelimit lambda$containsIn$0(Lcom/tencent/tsf/ratelimit/domain/Ratelimit$Rule;Lcom/tencent/tsf/ratelimit/domain/Ratelimit$Rule;)Z com.tencent.tsf.ratelimit.domain.Ratelimit setRules(Ljava/util/List;)V com.tencent.tsf.ratelimit.domain.Ratelimit isValidRequest(Z)Z com.tencent.tsf.ratelimit.domain.Ratelimit getRequestIdentity()Ljava/lang/String; com.tencent.tsf.ratelimit.domain.Ratelimit setNamespaceId(Ljava/lang/String;)V com.tencent.tsf.ratelimit.domain.Ratelimit containsIn(Ljava/util/List;)Z com.tencent.tsf.ratelimit.domain.Ratelimit isDimensionConflict(Ljava/util/List;)Z com.tencent.tsf.ratelimit.domain.Ratelimit getNamespaceId()Ljava/lang/String; com.tencent.tsf.ratelimit.domain.Ratelimit getServiceName()Ljava/lang/String; com.tencent.tsf.ratelimit.domain.Ratelimit setServiceName(Ljava/lang/String;)V com.tencent.tsf.common.proxy.Application <init>()V com.tencent.tsf.common.proxy.Application setApplicationId(Ljava/lang/String;)V com.tencent.tsf.common.proxy.Application getMicroserviceType()Ljava/lang/String; com.tencent.tsf.common.proxy.Application setMicroserviceType(Ljava/lang/String;)V com.tencent.tsf.common.proxy.Application getApplicationId()Ljava/lang/String; com.tencent.tsf.ratelimit.proxy.Microservice <init>()V com.tencent.tsf.ratelimit.proxy.Microservice setMicroserviceName(Ljava/lang/String;)V com.tencent.tsf.ratelimit.proxy.Microservice setNamespaceId(Ljava/lang/String;)V com.tencent.tsf.ratelimit.proxy.Microservice getMicroserviceName()Ljava/lang/String; com.tencent.tsf.ratelimit.proxy.Microservice getNamespaceId()Ljava/lang/String; com.tencent.tsf.ratelimit.proxy.Microservice getMicroserviceId()Ljava/lang/String; com.tencent.tsf.ratelimit.proxy.Microservice setMicroserviceId(Ljava/lang/String;)V com.tencent.tsf.common.TsfPageQuery <init>()V com.tencent.tsf.common.TsfPageQuery clear()V com.tencent.tsf.common.TsfPageQuery getOffset()Ljava/lang/Integer; com.tencent.tsf.common.TsfPageQuery setOffset(Ljava/lang/Integer;)V com.tencent.tsf.common.TsfPageQuery initDefault()V com.tencent.tsf.common.TsfPageQuery setSearchWord(Ljava/lang/String;)V com.tencent.tsf.common.TsfPageQuery getOrderType()Ljava/lang/Integer; com.tencent.tsf.common.TsfPageQuery getOrderTypeStr()Ljava/lang/String; com.tencent.tsf.common.TsfPageQuery setOrderType(Ljava/lang/Integer;)V com.tencent.tsf.common.TsfPageQuery getOrderBy()Ljava/lang/String; com.tencent.tsf.common.TsfPageQuery setOrderBy(Ljava/lang/String;)V com.tencent.tsf.common.TsfPageQuery getRealPage()I com.tencent.tsf.common.TsfPageQuery transerPageQuery(Lcom/tencent/tsf/common/TsfPageQuery;)V com.tencent.tsf.common.TsfPageQuery getSearchWordLikeStr()Ljava/lang/String; com.tencent.tsf.common.TsfPageQuery getLimit()Ljava/lang/Integer; com.tencent.tsf.common.TsfPageQuery setLimit(Ljava/lang/Integer;)V com.tencent.tsf.common.TsfPageQuery getSearchWord()Ljava/lang/String; Affect(row-cnt:43) cost in 12 ms.
該指令為非實時返回指令,默認 120s 返回一次統計值。
統計區間時間段內,方法執行的總數、成功次數、失敗次數、平均執行率、失敗比例 等信息。
參數說明
[arthas@8738]$ monitor -h USAGE: monitor [-b] [-c <value>] [--exclude-class-pattern <value>] [-h] [-n <value>] [--listenerId <value>] [-E <value>] [-v] class-pattern method-pattern [condition-express] SUMMARY: Monitor method execution statistics, e.g. total/success/failure count, average rt, fail rate, etc. Examples: monitor org.apache.commons.lang.StringUtils isBlank monitor org.apache.commons.lang.StringUtils isBlank -c 5 monitor org.apache.commons.lang.StringUtils isBlank params[0]!=null monitor -b org.apache.commons.lang.StringUtils isBlank params[0]!=null monitor -E org\.apache\.commons\.lang\.StringUtils isBlank WIKI: https://arthas.aliyun.com/doc/monitor OPTIONS: -b, --before Evaluate the condition-express before method invoke -c, --cycle <value> The monitor interval (in seconds), 60 seconds by default --exclude-class-pattern <value> exclude class name pattern, use either '.' or '/' as separator -h, --help this help -n, --limits <value> Threshold of execution times --listenerId <value> The special listenerId -E, --regex <value> Enable regular expression to match (wildcard matching by default) -v, --verbose Enables print verbose information, default value false. <class-pattern> Path and classname of Pattern Matching <method-pattern> Method of Pattern Matching <condition-express> Conditional expression in ognl style, for example: TRUE : 1==1 TRUE : true FALSE : false TRUE : 'params.length>=0' FALSE : 1==2 '#cost>100'
使用舉例
[arthas@8738]$ monitor com.tencent.tsf.resource.ns.dao.NamespaceDao * Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 15) cost in 104 ms, listenerId: 6 timestamp class method total success fail avg-rt(ms) fail-rate ---------------------------------------------------------------------------------------------------------------------------------------------------- 2021-09-09 18:26:58 com.tencent.tsf.resource.ns.dao.NamespaceDao countList 12 12 0 1.08 0.00% 2021-09-09 18:26:58 com.tencent.tsf.resource.ns.dao.NamespaceDao getAuthWhereClause 28 28 0 0.18 0.00% 2021-09-09 18:26:58 com.tencent.tsf.resource.ns.dao.NamespaceDao findList 2 2 0 1.09 0.00%關于Arthas在線java進程診斷工具怎么用問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
上述就是小編為大家分享的Arthas在線java進程診斷工具怎么用了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。