- Arthas是阿里的一款開源的線上JVM運(yùn)維工具。開源地址:Github-alibaba/arthas ,最近由于線上問題頻繁,但面對龐大的用戶量见转,我們無法做出及時的重啟乘客,為此入手Arthas浪默,旨在快速定位線上問題,解決用戶困擾
安裝
快速安裝
-
使用
arthas-boot
(推薦)下載
arthas-boot.jar
,然后用java -jar
的方式啟動:wget https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar
-
如果下載速度比較慢,可以使用aliyun的鏡像:
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
-
如果從github下載有問題,可以使用gitee鏡像
wget https://arthas.gitee.io/arthas-boot.jar
使用as.sh
安裝
-
Arthas 支持在 Linux/Unix/Mac 等平臺上一鍵安裝
curl -L https://alibaba.github.io/arthas/install.sh | sh
對于
as.sh
方式,在安裝的過程中還需要走互聯(lián)網(wǎng)逾条,為此對應(yīng)博主這種企業(yè)內(nèi)網(wǎng)無法聯(lián)通外部網(wǎng)絡(luò)的環(huán)境下吃警,該方式并不通用上述命令會下載啟動腳本文件
as.sh
到當(dāng)前目錄挑豌,你可以放在任何地方或?qū)⑵浼尤氲?$PATH
中铝阐。-
直接在shell下面執(zhí)行
./as.sh
,就會進(jìn)入交互界面。也可以執(zhí)行./as.sh -h
來獲取更多參數(shù)信息挟憔。- 使用
as.sh
腳本執(zhí)行的時候达传,需要先安裝telnet
脯燃,否則會報錯
- 使用
-
如果從github下載有問題逝嚎,可以使用gitee鏡像
curl -L https://arthas.gitee.io/install.sh | sh
全量安裝
-
下載完成后
arthas-packaging-3.1.1-bin
解壓后挽铁,在文件夾里有arthas-boot.jar
够掠,直接用java -jar
的方式啟動:java -jar arthas-boot.jar
-
打印幫助信息:
java -jar arthas-boot.jar -h
卸載
-
在 Linux/Unix/Mac 平臺
rm -rf ~/.arthas/ rm -rf ~/logs/arthas
Windows平臺直接刪除user home下面的
.arthas
和logs/arthas
目錄
啟動
java -jar arthas-boot.jar --target-ip 0.0.0.0
默認(rèn)情況下, arthas server 偵聽的是
127.0.0.1
這個IP,如果希望遠(yuǎn)程可以訪問增淹,可以使用--target-ip
的參數(shù)-
arthas-boot
是Arthas
的啟動程序拳喻,它啟動后,會列出所有的 Java 進(jìn)程,輸入需要診斷的目標(biāo)進(jìn)程序號即可
-
Arthas支持通過 Web Socket來連接陨溅。
- 當(dāng)在本地啟動時,可以訪問
http://127.0.0.1:8563/
,通過瀏覽器來使用 Arthas。 - 輸入
help
可以看到常用的幫助命令:
- 當(dāng)在本地啟動時,可以訪問
-
arthas-boot.jar
支持很多參數(shù),可以執(zhí)行java -jar arthas-boot.jar -h
查看D:\arthas>java -jar arthas-boot.jar -h [INFO] arthas-boot version: 3.1.1 Usage: arthas-boot [-v] [--session-timeout <value>] [--arthas-home <value>] [--use-version <value>] [--target-ip <value>] [--attach-only] [--height <value>] [--width <value>] [-c <value>] [--repo-mirror <value>] [--versions] [-f <value>] [--telnet-port <value>] [--use-http] [-h] [--http-port <value>] [pid] Bootstrap Arthas EXAMPLES: java -jar arthas-boot.jar <pid> java -jar arthas-boot.jar --target-ip 0.0.0.0 java -jar arthas-boot.jar --telnet-port 9999 --http-port -1 java -jar arthas-boot.jar -c 'sysprop; thread' <pid> java -jar arthas-boot.jar -f batch.as <pid> java -jar arthas-boot.jar --use-version 3.1.1 java -jar arthas-boot.jar --versions java -jar arthas-boot.jar --session-timeout 3600 java -jar arthas-boot.jar --attach-only java -jar arthas-boot.jar --repo-mirror aliyun --use-http WIKI: https://alibaba.github.io/arthas Options and Arguments: -v,--verbose Verbose, print debug info. --session-timeout <value> The session timeout seconds, default 1800 (30min) --arthas-home <value> The arthas home --use-version <value> Use special version arthas --target-ip <value> The target jvm listen ip, default 127.0.0.1 --attach-only Attach target process only, do not connect --height <value> arthas-client terminal height --width <value> arthas-client terminal width -c,--command <value> Command to execute, multiple commands separated by ; --repo-mirror <value> Use special maven repository mirror, value is center/aliyun or http repo url. --versions List local and remote arthas versions -f,--batch-file <value> The batch file to execute --telnet-port <value> The target jvm listen telnet port, default 3658 --use-http Enforce use http to download, default use https -h,--help Print usage --http-port <value> The target jvm listen http port, default 8563 <pid> Target pid
使用技巧
- 每個命令,都可以加上
-h
來查看對應(yīng)的幫助信息,例如:sc -h
-
Tab
自動補(bǔ)全推掸,例如:sysprop java.
按下Tab
鍵噪服,會補(bǔ)全對應(yīng)的key
- 支持常見的命令行快捷鍵呻顽,比如
ctrl+a/e
喉前,更多輸入keymap
查看 - 歷史命令補(bǔ)全,輸入一半時,按下
Up/↑
或Down/↓
來匹配,例如sysprop ja
之后,按下↑
會幫你自動補(bǔ)全 - 管道命令支持,例如
sysprop | wc -l
退出
-
exit
或quit
可以退出 Arthas- 退出 Arthas 之后,還可以再次使用
java -jar arthas-boot.jar
來鏈接 -
exit/quit
命令只是退出當(dāng)前 session,arthas server
還在目標(biāo)進(jìn)程中運(yùn)行肉迫,shutdown
命令才能完全退出 Arthas
- 退出 Arthas 之后,還可以再次使用
常用命令
dashboard
dashboard
命令可以查看系統(tǒng)的實(shí)時數(shù)據(jù)面板族购。-
q
或ctrl+c
可以退出數(shù)據(jù)面展示
數(shù)據(jù)說明:
- ID: Java級別的線程ID朝墩,注意這個ID不能跟jstack中的nativeID一一對應(yīng)
- NAME: 線程名
- GROUP: 線程組名
- PRIORITY: 線程優(yōu)先級, 1~10之間的數(shù)字鹿霸,越大表示優(yōu)先級越高
- STATE: 線程的狀態(tài)
- CPU%: 線程消耗的cpu占比肛冶,采樣100ms荣刑,將所有線程在這100ms內(nèi)的cpu使用量求和爱只,再算出每個線程的cpu使用占比。
- TIME: 線程運(yùn)行總時間畦粮,數(shù)據(jù)格式為分:秒
- INTERRUPTED: 線程當(dāng)前的中斷位狀態(tài)
- DAEMON: 是否是daemon線程
thread
查看當(dāng)前線程信息儒将,查看線程的堆棧
-
參數(shù)說明
參數(shù)名稱 參數(shù)說明 id 線程id [n:] 指定最忙的前N個線程并打印堆棧 [b] 找出當(dāng)前阻塞其他線程的線程 [i <value>
]指定cpu占比統(tǒng)計的采樣間隔砰逻,單位為毫秒 thread 1
打印線程 ID 1 的線程棧信息
-
查看 CPU 使用率 top n 的線程的棧闸翅,當(dāng)前最忙的前 n 個線程:
thread -n 3
-
查看 5 秒內(nèi)的 CPU 使用率 top n 的線程棧:
thread -n 3 -i 5000
* 在該命令中,arthas 會停頓5秒,進(jìn)行計算得出結(jié)果,為阿里點(diǎn)贊
-
查看線程是否有阻塞:
thread -b
- 有時候我們發(fā)現(xiàn)應(yīng)用出現(xiàn)卡頓,未響應(yīng), 通常是由于某個線程占用著某個鎖, 并且其他線程都在等待這把鎖的釋放。 為了排查這類問題,此時使用
-b
參數(shù)资柔,可以找到問題所在睁枕。- 目前只支持找出synchronized關(guān)鍵字阻塞住的線程, 如果是
java.util.concurrent.Lock
, 目前還不支持
- 目前只支持找出synchronized關(guān)鍵字阻塞住的線程, 如果是
- 有時候我們發(fā)現(xiàn)應(yīng)用出現(xiàn)卡頓,未響應(yīng), 通常是由于某個線程占用著某個鎖, 并且其他線程都在等待這把鎖的釋放。 為了排查這類問題,此時使用
jvm
-
查看當(dāng)前JVM信息
$ jvm RUNTIME ----------------------------------------------------------------------------------------------------------------------- MACHINE-NAME 18280@DESKTOP-040TJ8N JVM-START-TIME 2019-07-21 22:52:26 MANAGEMENT-SPEC-VERSION 1.2 SPEC-NAME Java Virtual Machine Specification SPEC-VENDOR Oracle Corporation SPEC-VERSION 1.8 VM-NAME Java HotSpot(TM) 64-Bit Server VM VM-VENDOR Oracle Corporation VM-VERSION 25.131-b11 INPUT-ARGUMENTS -Djava.util.logging.config.file=H:\Development\ide\ideacfg\system\tomcat\Unnamed_pl atform\conf\logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:2139,suspend=y,server=n -javaagent:H:\Development\ide\ideacfg\system\captureAgent\debugger-agent.jar=file:/ C:/Users/guosucong/AppData/Local/Temp/capture5938.props -Dcom.sun.management.jmxremote= -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=127.0.0.1 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=D:\Development\Tomcat\apache-tomcat-7.0.75\endorsed -Dcatalina.base=H:\Development\ide\ideacfg\system\tomcat\Unnamed_platform -Dcatalina.home=D:\Development\Tomcat\apache-tomcat-7.0.75 -Djava.io.tmpdir=D:\Development\Tomcat\apache-tomcat-7.0.75\temp CLASS-PATH D:\Development\Tomcat\apache-tomcat-7.0.75\bin\bootstrap.jar;D:\Development\Tomcat\ apache-tomcat-7.0.75\bin\tomcat-juli.jar;H:\Development\ide\ideacfg\system\captureA gent\debugger-agent.jar BOOT-CLASS-PATH D:\Development\Java\jdk1.8.0_131\jre\lib\resources.jar;D:\Development\Java\jdk1.8.0 _131\jre\lib\rt.jar;D:\Development\Java\jdk1.8.0_131\jre\lib\sunrsasign.jar;D:\Deve lopment\Java\jdk1.8.0_131\jre\lib\jsse.jar;D:\Development\Java\jdk1.8.0_131\jre\lib \jce.jar;D:\Development\Java\jdk1.8.0_131\jre\lib\charsets.jar;D:\Development\Java\ jdk1.8.0_131\jre\lib\jfr.jar;D:\Development\Java\jdk1.8.0_131\jre\classes;H:\Develo pment\ide\ideacfg\system\captureAgent\debugger-agent-storage.jar LIBRARY-PATH D:\Development\Java\jdk1.8.0_131\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C: \Windows;C:\ProgramData\Oracle\Java\javapath;%APPCAN_PATH%;D:\Development\Oracle\DB \product\11.2.0\dbhome_1\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbe m;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\NVIDIA Corpora tion\PhysX\Common;D:\VisualSVN Server\bin;D:\TortoiseSVN\bin;C:\ProgramData\chocola tey\bin;H:\Android\sdk\tools;H:\Android\sdk\platform-tools;D:\Development\TortoiseG it\bin;D:\Development\nodejs\;D:\Microsoft VS Code\bin;D:\Development\Java\jdk1.8.0 _131\bin;D:\Development\Tomcat\apache-tomcat-7.0.75\bin;D:\Development\apache-maven -3.2.5\bin;D:\auto-tsschecker_v2.1;D:\Development\MySQL\Mysql5_7\MySQLServer\bin;D: \Development\apache-cxf-2.4.2\bin;C:\Users\guosucong\AppData\Local\Microsoft\Window sApps;D:\Development\kotlinc\bin;D:\Development\spring-2.0.0.BUILD-SNAPSHOT\bin;D:\ Development\redis;D:\Development\gradle-4.4.1\bin;H:\Android\sdk\platform-tools;H:\ Android\sdk\tools;D:\Microsoft VS Code\bin;D:\Development\apache-ant-1.9.9\bin;D:\D evelopment\sonarqube-6.7.4\bin;C:\Users\guosucong\AppData\Roaming\npm;D:\Developmen t\Git\bin;D:\Development\flutter\bin;. ----------------------------------------------------------------------------------------------------------------------- CLASS-LOADING ----------------------------------------------------------------------------------------------------------------------- LOADED-CLASS-COUNT 10418 TOTAL-LOADED-CLASS-COUNT 10418 UNLOADED-CLASS-COUNT 0 IS-VERBOSE false ----------------------------------------------------------------------------------------------------------------------- COMPILATION ----------------------------------------------------------------------------------------------------------------------- NAME HotSpot 64-Bit Tiered Compilers TOTAL-COMPILE-TIME 46848(ms) ----------------------------------------------------------------------------------------------------------------------- GARBAGE-COLLECTORS ----------------------------------------------------------------------------------------------------------------------- PS Scavenge 13/216(ms) [count/time] PS MarkSweep 3/291(ms) [count/time] ----------------------------------------------------------------------------------------------------------------------- MEMORY-MANAGERS ----------------------------------------------------------------------------------------------------------------------- CodeCacheManager Code Cache Metaspace Manager Metaspace Compressed Class Space PS Scavenge PS Eden Space PS Survivor Space PS MarkSweep PS Eden Space PS Survivor Space PS Old Gen ----------------------------------------------------------------------------------------------------------------------- MEMORY ----------------------------------------------------------------------------------------------------------------------- HEAP-MEMORY-USAGE 1436024832(1.34 GiB)/268435456(256.00 MiB)/3791650816(3.53 GiB)/1040965944(992.74 M [committed/init/max/used] iB) NO-HEAP-MEMORY-USAGE 113754112(108.48 MiB)/2555904(2.44 MiB)/-1(-1 B)/111507424(106.34 MiB) [committed/init/max/used] PENDING-FINALIZE-COUNT 0 ----------------------------------------------------------------------------------------------------------------------- OPERATING-SYSTEM ----------------------------------------------------------------------------------------------------------------------- OS Windows 10 ARCH amd64 PROCESSORS-COUNT 8 LOAD-AVERAGE -1.0 VERSION 10.0 ----------------------------------------------------------------------------------------------------------------------- THREAD ----------------------------------------------------------------------------------------------------------------------- COUNT 52 DAEMON-COUNT 23 PEAK-COUNT 53 STARTED-COUNT 71 DEADLOCK-COUNT 0 ----------------------------------------------------------------------------------------------------------------------- FILE-DESCRIPTOR ----------------------------------------------------------------------------------------------------------------------- MAX-FILE-DESCRIPTOR-COUNT -1 OPEN-FILE-DESCRIPTOR-COUNT -1 Affect(row-cnt:0) cost in 4 ms.
-
THREAD相關(guān)
- COUNT: JVM當(dāng)前活躍的線程數(shù)
- DAEMON-COUNT: JVM當(dāng)前活躍的守護(hù)線程數(shù)
- PEAK-COUNT: 從JVM啟動開始曾經(jīng)活著的最大線程數(shù)
- STARTED-COUNT: 從JVM啟動開始總共啟動過的線程次數(shù)
- DEADLOCK-COUNT: JVM當(dāng)前死鎖的線程數(shù)
-
文件描述符相關(guān)
- MAX-FILE-DESCRIPTOR-COUNT:JVM進(jìn)程最大可以打開的文件描述符數(shù)
- OPEN-FILE-DESCRIPTOR-COUNT:JVM當(dāng)前打開的文件描述符數(shù)
sc
- 查找 JVM 加載類尤慰,
Search-Class
的簡寫萎河,這個命令能搜索出所有已經(jīng)加載到 JVM 中的 Class 信息擎椰,sc -d *MathGame
- 如果搜索的是接口达舒,還會搜索所有的實(shí)現(xiàn)類趾代。比如查看所有的
Filter
實(shí)現(xiàn)類:
sc javax.servlet.Filter
-d
參數(shù)可以打印出類加載的具體信息飘哨,方便定位類加載問題
sc
支持通配符淘正,比如搜索所有的 StringUtils
:
Copysc *StringUtils
[圖片上傳失敗...(image-2b1ed8-1590935866588)]
打印類的 Field
信息:
Copysc -d -f demo.MathGame
sm
- 查看已加載類的方法信息
Search-Method
的簡寫惩淳,這個命令能搜索出所有已經(jīng)加載了 Class 信息的方法信息激蹲。 - sm 命令只能看到由當(dāng)前類所聲明 (declaring) 的方法策泣,父類則無法看到
- 查看 String 類的全部方法:
sm java.lang.String
- 查看具體方法的信息:
sm java.lang.String toString
- 通過
-d
參數(shù)可以打印函數(shù)的具體屬性钙畔,展示每個方法的詳細(xì)信息
sm -d java.math.RoundingMode
jad
- 反編譯指定已加載類的源碼 ,
jad
命令將 JVM 中實(shí)際運(yùn)行的 class 的 byte code 反編譯成 java 代碼挪鹏,便于你理解業(yè)務(wù)邏輯 - 參數(shù)說明
參數(shù)名稱 | 參數(shù)說明 |
---|---|
class-pattern | 類名表達(dá)式匹配 |
[c:] |
類所屬 ClassLoader 的 hashcode |
[E] | 開啟正則表達(dá)式匹配返顺,默認(rèn)為通配符匹配 |
- 通過
jad
命令反編譯代碼:
jad demo.MatthGame
$ jad com.platform.controller.SysConfigController
ClassLoader:
+-WebappClassLoader
context: /platform
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
java.net.URLClassLoader@2d127a61
+-java.net.URLClassLoader@2d127a61
+-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@6dde5c8c
Location:
/H:/Development/ideaworkspace/platform/platform-framework/target/platform-framework/WEB-INF/classes/
/*
* Decompiled with CFR 0_132.
*
* Could not load the following classes:
* com.platform.annotation.SysLog
* com.platform.controller.AbstractController
* com.platform.entity.SysConfigEntity
* com.platform.service.SysConfigService
* com.platform.utils.PageUtils
* com.platform.utils.Query
* com.platform.utils.R
* com.platform.validator.ValidatorUtils
* org.apache.shiro.authz.annotation.RequiresPermissions
* org.springframework.beans.factory.annotation.Autowired
* org.springframework.web.bind.annotation.PathVariable
* org.springframework.web.bind.annotation.RequestBody
* org.springframework.web.bind.annotation.RequestMapping
* org.springframework.web.bind.annotation.RequestParam
* org.springframework.web.bind.annotation.RestController
*/
package com.platform.controller;
import com.platform.annotation.SysLog;
import com.platform.controller.AbstractController;
import com.platform.entity.SysConfigEntity;
import com.platform.service.SysConfigService;
import com.platform.utils.PageUtils;
import com.platform.utils.Query;
import com.platform.utils.R;
import com.platform.validator.ValidatorUtils;
import java.util.List;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value={"/sys/config"})
public class SysConfigController
extends AbstractController {
@Autowired
private SysConfigService sysConfigService;
@RequestMapping(value={"/list"})
@RequiresPermissions(value={"sys:config:list"})
public R list(@RequestParam Map<String, Object> params) {
Query query = new Query(params);
List configList = this.sysConfigService.queryList((Map)query);
int total = this.sysConfigService.queryTotal((Map)query);
PageUtils pageUtil = new PageUtils(configList, total, query.getLimit(), query.getPage());
return R.ok().put("page", (Object)pageUtil);
}
@RequestMapping(value={"/info/{id}"})
@RequiresPermissions(value={"sys:config:info"})
public R info(@PathVariable(value="id") Long id) {
SysConfigEntity config = this.sysConfigService.queryObject(id);
return R.ok().put("config", (Object)config);
}
@SysLog(value="\u4fdd\u5b58\u914d\u7f6e")
@RequestMapping(value={"/save"})
@RequiresPermissions(value={"sys:config:save"})
public R save(@RequestBody SysConfigEntity config) {
ValidatorUtils.validateEntity((Object)config, (Class[])new Class[0]);
this.sysConfigService.save(config);
return R.ok();
}
@SysLog(value="\u4fee\u6539\u914d\u7f6e")
@RequestMapping(value={"/update"})
@RequiresPermissions(value={"sys:config:update"})
public R update(@RequestBody SysConfigEntity config) {
ValidatorUtils.validateEntity((Object)config, (Class[])new Class[0]);
this.sysConfigService.update(config);
return R.ok();
}
@SysLog(value="\u5220\u9664\u914d\u7f6e")
@RequestMapping(value={"/delete"})
@RequiresPermissions(value={"sys:config:delete"})
public R delete(@RequestBody Long[] ids) {
this.sysConfigService.deleteBatch(ids);
return R.ok();
}
}
- 通過該工具忆谓,我們往往能看到線上當(dāng)前代碼的情況勾扭,有時候在線上環(huán)境中手頭沒有源代碼的情況之下身辨,可以通過該命令對指定的類進(jìn)行反編譯泌豆,找到問題的根源,從而快速的定位問題與獲取解決方案,該命令可以與其他命令結(jié)合官疲,反編譯后得出源文件颖榜,對文件代碼進(jìn)行修改后通過
mc
命令編譯且蓬,通過redefine
熱加載回JVM內(nèi)存冯事,達(dá)到無需重啟摔笤,修復(fù)線上問題梯投,但是對于反編譯出來的源代碼咆疗,可能出現(xiàn)錯亂問題毡们,所以還是慎重使用红氯,一般用于查看線上問題塞栅。
mc
redefine
monitor
trace
watch
watch
命令可以查看函數(shù)的:
- 參數(shù)
- 返回值
- 異常信息
Copywatch demo.MathGame primeFactors returnObj
[圖片上傳失敗...(image-c6fd81-1590935866588)]
Copywatch com.example.demo.arthas.user.UserController * '{params, throwExp}' -x 2
- 第一個參數(shù)是類名,支持通配
- 第二個參數(shù)是函數(shù)名,支持通配
- 第三個參數(shù)是定義返回值
-
-x 2
是為了將結(jié)果展開
返回值表達(dá)式實(shí)際是一個 ognl
表示涎显,支持一些內(nèi)置對象:
- loader
- clazz
- method
- target
- params
- returnObj
- throwExp
- isBefore
- isThrow
- isReturn
watch命令支持按請求耗時進(jìn)行過濾:
watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'
Arthas在 watch/trace 等命令時讨勤,實(shí)際上是修改了應(yīng)用的字節(jié)碼刨晴,插入增強(qiáng)的代碼。顯式執(zhí)行 reset 命令,可以清除掉這些增強(qiáng)代碼
ognl
獲取靜態(tài)類的靜態(tài)字段:
ognl '@demo.MathGame@random'
具體,查看執(zhí)行ognl表達(dá)式
trace
方法內(nèi)部調(diào)用路徑,并輸出方法路徑上的每個節(jié)點(diǎn)上耗時
trace 命令能主動搜索 class-pattern/method-pattern
對應(yīng)的方法調(diào)用路徑吉嚣,渲染和統(tǒng)計整個調(diào)用鏈路上的所有性能開銷和追蹤調(diào)用鏈路
參數(shù)名稱 | 參數(shù)說明 |
---|---|
class-pattern | 類名表達(dá)式匹配 |
method-pattern | 方法名表達(dá)式匹配 |
condition-express | 條件表達(dá)式 |
[E] | 開啟正則表達(dá)式匹配琐馆,默認(rèn)為通配符匹配 |
[n:] | 命令執(zhí)行次數(shù) |
#cost | 方法執(zhí)行耗時 |
很多時候我們只想看到某個方法的 rt 大于某個時間之后的 trace 結(jié)果滋饲,現(xiàn)在 Arthas 可以按照方法執(zhí)行的耗時來進(jìn)行過濾了呵曹,例如 trace *StringUtils isBlank '#cost>100'
表示當(dāng)執(zhí)行時間超過 100ms 的時候砍聊,才會輸出 trace 的結(jié)果。
watch/stack/trace
這個三個命令都支持 #cost
trace 函數(shù):
$ trace demo.MathGame run
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 42 ms.
`---ts=2018-12-04 00:44:17;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
`---[10.611029ms] demo.MathGame:run()
+---[0.05638ms] java.util.Random:nextInt()
+---[10.036885ms] demo.MathGame:primeFactors()
`---[0.170316ms] demo.MathGame:print()
過濾掉 jdk 的函數(shù):
$ trace -j demo.MathGame run
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 31 ms.
`---ts=2018-12-04 01:09:14;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
`---[5.190646ms] demo.MathGame:run()
+---[4.465779ms] demo.MathGame:primeFactors()
`---[0.375324ms] demo.MathGame:print()
-
-j
: jdkMethodSkip, skip jdk method trace
trace 在執(zhí)行的過程中本身是會有一定的性能開銷阳欲,在統(tǒng)計的報告中并未像 JProfiler 一樣預(yù)先減去其自身的統(tǒng)計開銷
stack
輸出當(dāng)前方法被調(diào)用的調(diào)用路徑
很多時候我們都知道一個方法被執(zhí)行,但這個方法被執(zhí)行的路徑非常多,或者你根本就不知道這個方法是從那里被執(zhí)行了,此時你需要的是 stack 命令。
參數(shù)名稱 | 參數(shù)說明 |
---|---|
class-pattern | 類名表達(dá)式匹配 |
method-pattern | 方法名表達(dá)式匹配 |
condition-express | 條件表達(dá)式 |
[E] | 開啟正則表達(dá)式匹配钾军,默認(rèn)為通配符匹配 |
[n:] | 執(zhí)行次數(shù)限制 |
據(jù)執(zhí)行時間來過濾:
$ stack demo.MathGame primeFactors '#cost>5'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 35 ms.
ts=2018-12-04 01:35:58;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
@demo.MathGame.run()
at demo.MathGame.main(MathGame.java:16)
實(shí)戰(zhàn)
啟動 Spring Boot Demo
wget https://github.com/hengyunabc/katacoda-scenarios/raw/master/demo-arthas-spring-boot.jar
java -jar demo-arthas-spring-boot.jar
啟動 arthas-boot
wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar --target-ip 0.0.0.0
就像基礎(chǔ)教程說過的剿配,選擇目標(biāo)進(jìn)程
查看 JVM 信息
sysprop
- 查看當(dāng)前 JVM 的系統(tǒng)屬性(
System Property
)-
sysprop
打印所有System Properties
- 指定單個 key:
sysprop java.version
- 通過 grep 過濾:
sysprop|grep user
- 設(shè)置新的value:
sysprop testKey testValue
-
[圖片上傳失敗...(image-51b975-1590935866588)]
sysenv
-
sysenv
命令查看當(dāng)前 JVM 的環(huán)境屬性(System Environment Variables
)
[圖片上傳失敗...(image-e209dc-1590935866588)]
-
也是支持查看單個環(huán)境變量值:
sysenv USER