Arthas基本操作以命令大全、開啓日誌功能

1.Arthas 能爲你做什麼?

Arthas是Alibaba開源的Java診斷工具,深受開發者喜愛。
當你遇到以下類似問題而束手無策時,Arthas可以幫助你解決:
這個類從哪個 jar 包加載的?爲什麼會報各種類相關的 Exception?
我改的代碼爲什麼沒有執行到?難道是我沒 commit?分支搞錯了?
遇到問題無法在線上 debug,難道只能通過加日誌再重新發布嗎?
線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!
是否有一個全局視角來查看系統的運行狀況?
有什麼辦法可以監控到JVM的實時運行狀態?
Arthas支持JDK 6+,支持Linux/Mac/Winodws,採用命令行交互模式,同時提供豐富的 Tab 自動補全功能,進一步方便進行問題的定位和診斷。

GitHub地址:https://github.com/alibaba/arthas
用戶文檔:https://alibaba.github.io/arthas/

2.Arthas Install

2.1使用arthas-boot
下載arthas-boot.jar,然後用java -jar的方式啓動:

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

打印幫助信息

java -jar arthas-boot.jar -h

2.2使用as.sh安裝
Arthas 支持在 Linux/Unix/Mac 等平臺上一鍵安裝,請複製以下內容,並粘貼到命令行中,敲 回車 執行即可:

curl -L https://alibaba.github.io/arthas/install.sh | sh

上述命令會下載啓動腳本文件 as.sh 到當前目錄,你可以放在任何地方或將其加入到 $PATH 中。
直接在shell下面執行./as.sh,就會進入交互界面。
也可以執行./as.sh -h來獲取更多參數信息。

2.3通過Cloud Toolkit插件使用Arthas

IDEA與eclipse插件安裝圖文教程
Cloud Toolkit插件官方介紹

2.4卸載

在 Linux/Unix/Mac 平臺
刪除下面文件:

rm -rf ~/.arthas/
rm -rf ~/logs/arthas

Windows平臺直接刪除user home下面的.arthas和logs/arthas目錄

3.命令列表

3.1基礎命令

help——查看命令幫助信息
cls——清空當前屏幕區域
session——查看當前會話的信息
reset——重置增強類,將被 Arthas 增強過的類全部還原,Arthas 服務端關閉時會重置所有增強過的類
version——輸出當前目標 Java 進程所加載的 Arthas 版本號
history——打印命令歷史
quit——退出當前 Arthas 客戶端,其他 Arthas 客戶端不受影響
shutdown——關閉 Arthas 服務端,所有 Arthas 客戶端全部退出
keymap——Arthas快捷鍵列表及自定義快捷鍵

3.2Jvm相關

dashboard——當前系統的實時數據面板
thread——查看當前 JVM 的線程堆棧信息
jvm——查看當前 JVM 的信息
sysprop——查看和修改JVM的系統屬性
sysenv——查看JVM的環境變量
getstatic——查看類的靜態屬性
ognl——執行ognl表達式
mbean——查看 Mbean 的信息

3.3class/classloader相關

sc——查看JVM已加載的類信息
sm——查看已加載類的方法信息
jad——反編譯指定已加載類的源碼
mc——內存編繹器,內存編繹.java文件爲.class文件
redefine——加載外部的.class文件,redefine到JVM裏
dump——dump 已加載類的 byte code 到特定目錄
classloader——查看classloader的繼承樹,urls,類加載信息,使用classloader去getResource

3.4monitor/watch/trace相關

請注意,這些命令,都通過字節碼增強技術來實現的,會在指定類的方法中插入一些切面來實現數據統計和觀測,因此在線上、預發使用時,請儘量明確需要觀測的類、方法以及條件,診斷結束要執行 shutdown 或將增強過的類執行 reset 命令。
monitor——方法執行監控
watch——方法執行數據觀測
trace——方法內部調用路徑,並輸出方法路徑上的每個節點上耗時
stack——輸出當前方法被調用的調用路徑
tt——方法執行數據的時空隧道,記錄下指定方法每次調用的入參和返回信息,並能對這些不同的時間下調用進行觀測
3.5options
options——查看或設置Arthas全局開關

4實例

4.1.啓動Arthas
在命令行下面執行(使用和目標進程一致的用戶啓動,否則可能attach失敗):

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

執行該程序的用戶需要和目標進程具有相同的權限。比如以admin用戶來執行:sudo su admin && java -jar arthas-boot.jar 或 sudo -u admin -EH java -jar arthas-boot.jar。
如果attach不上目標進程,可以查看~/logs/arthas/ 目錄下的日誌。
如果下載速度比較慢,可以使用aliyun的鏡像:java -jar arthas-boot.jar --repo-mirror aliyun --use-http
java -jar arthas-boot.jar -h 打印更多參數信息。
選擇應用java進程:

[root@wh-gbcom gidata]# java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.1.1
[INFO] Process 54355 already using port 3658
[INFO] Process 54355 already using port 8563
[INFO] Found existing java process, please choose one and hit RETURN.
 [1]: 54355 /home/xxx.jar
  [2]: 417757 /usr/lib/jenkins/jenkins.war

xxx進程是第1個,則輸入1,再輸入回車/enter。Arthas會attach到目標進程上,並輸出日誌:

[INFO] arthas home: /root/.arthas/lib/3.1.1/arthas
[INFO] The target process already listen port 3658, skip attach.
[INFO] arthas-client connect 127.0.0.1 3658
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.                           
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'                          
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.                          
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |                         
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'                          
                                                                                

wiki      https://alibaba.github.io/arthas                                      
tutorials https://alibaba.github.io/arthas/arthas-tutorials                     
version   3.1.1                                                                 
pid       54355                                                                 
time      2019-07-29 11:13:34     

4.2查看dashboard

$ dashboard 
ID                  NAME                                                        GROUP                                    PRIORITY            STATE               %CPU                TIME                INTERRUPTED         DAEMON              
152                 Timer-for-arthas-dashboard-838ac88e-342e-4e52-83ba-b07c3cf5 system                                   10                  RUNNABLE            57                  0:0                 false               true                
64                  SimplePauseDetectorThread_0                                 main                                     5                   TIMED_WAITING       12                  15:30               false               true                
66                  SimplePauseDetectorThread_2                                 main                                     5                   TIMED_WAITING       11                  15:44               false               true                
65                  SimplePauseDetectorThread_1                                 main                                     5                   TIMED_WAITING       9                   15:32               false               true                
57                  http-nio-9015-ClientPoller-0                                main                                     5                   RUNNABLE            2                   0:10                false               true                
143                 nioEventLoopGroup-2-1                                       system                                   10                  RUNNABLE            2                   0:0                 false               false               
80                  DataPublisher                                               main                                     5                   TIMED_WAITING       1                   0:13                false               true                
35                  SimplePauseDetectorThread_0                                 system                                   9                   TIMED_WAITING       1                   1:35                false               true                
33                  Abandoned connection cleanup thread                         main                                     5                   TIMED_WAITING       0                   0:6                 false               true                
140                 AsyncAppender-Worker-arthas-cache.result.AsyncAppender      system                                   9                   WAITING             0                   0:0                 false               true                
41                  AsyncResolver-bootstrap-0                                   main                                     5                   TIMED_WAITING       0                   0:0                 false               true                
88                  AsyncResolver-bootstrap-executor-0                          main                                     5                   WAITING             0                   0:0                 false               true                
138                 Attach Listener                                             system                                   9                   RUNNABLE            0                   0:0                 false               true                
31                  Catalina-utility-1                                          main                                     1                   TIMED_WAITING       0                   0:17                false               false               
87                  DestroyJavaVM                                               main                                     5                   RUNNABLE            0                   0:31                false               false               
42                  DiscoveryClient-0                                           main                                     5                   TIMED_WAITING       0                   0:1                 false               true                
43                  DiscoveryClient-1                                           main                                     5                   WAITING             0                   0:1                 false               true                
83                  DiscoveryClient-CacheRefreshExecutor-0                      main                                     5                   WAITING             0                   0:11                false               true                
84                  DiscoveryClient-HeartbeatExecutor-0                         main                                     5                   WAITING             0                   0:10                false               true                
44                  DiscoveryClient-InstanceInfoReplicator-0                    main                                     5                   TIMED_WAITING       0                   0:0                 false               true                
36                  Druid-ConnectionPool-Create-438123546                       main                                     5                   WAITING             0                   0:0                 false               true                
38                  Druid-ConnectionPool-Create-609389093                       main                                     5                   WAITING             0                   0:0                 false               true                
37                  Druid-ConnectionPool-Destroy-438123546                      main                                     5                   TIMED_WAITING       0                   0:0                 false               true                
39                  Druid-ConnectionPool-Destroy-609389093                      main                                     5                   TIMED_WAITING       0                   0:0                 false               true                
40                  Eureka-JerseyClient-Conn-Cleaner2                           main                                     5                   TIMED_WAITING       0                   0:0                 false               true                
3                   Finalizer                                                   system                                   8                   WAITING             0                   0:0                 false               true                
Memory                                              used             total            max               usage            GC                                                                                                                      
heap                                                566M             1057M            7033M             8.06%            gc.ps_scavenge.count                                        889                                                         
ps_eden_space                                       323M             602M             2623M             12.32%           gc.ps_scavenge.time(ms)                                     15532                                                       
ps_survivor_space                                   6M               7M               7M                99.88%           gc.ps_marksweep.count                                       4                                                           
ps_old_gen                                          236M             448M             5275M             4.48%            gc.ps_marksweep.time(ms)                                    637                                                         
nonheap                                             196M             203M             -1                96.52%                                                                                                                                   
code_cache                                          63M              64M              240M              26.37%                                                                                                                                   
metaspace                                           118M             124M             -1                95.62%                                                                                                                                   
compressed_class_space                              14M              15M              1024M             1.43%                                                                                                                                    
direct                                              88K              88K              -                 100.00%                                                                                                                                  
mapped                                              0K               0K               -                 NaN%                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
Runtime                                                                                                                                                                                                                                          
os.name                                                                                                                  Linux                                                                                                                   
os.version                                                                                                               3.10.0-957.21.3.el7.x86_64                                                                                              
java.version                                                                                                             1.8.0_212                                                                                                               
java.home                                                                                                                /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre                                                        
systemload.average                                                                                                       0.30                                                                                                                    
processors                                                                                                               32                                                                                                                      
uptime                                                                                                                   246111s        

4.3. 使用命令反編譯class文件

$ jad com.gbcom.gidata.alarm.entity.primary.ActiveAlarm

ClassLoader:                                                                                                                                                                                                                                     
+-org.springframework.boot.loader.LaunchedURLClassLoader@49c2faae                                                                                                                                                                                
  +-sun.misc.Launcher$AppClassLoader@70dea4e                                                                                                                                                                                                     
    +-sun.misc.Launcher$ExtClassLoader@620aa4ea                                                                                                                                                                                                  

Location:                                                                                                                                                                                                                                        
file:/home/gidata/GiDataServer/GiDataServer.jar!/BOOT-INF/classes!/                                                                                                                                                                              

/*
 * Decompiled with CFR 0_132.
 * 
 * Could not load the following classes:
 *  javax.persistence.Entity
 *  javax.persistence.GeneratedValue
 *  javax.persistence.GenerationType
 *  javax.persistence.Id
 *  javax.persistence.Table
 */
package com.gbcom.gidata.alarm.entity.primary;

import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="alarm_active")
public class ActiveAlarm {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private String alarmName;
    private String sno;
    private String name;
    private Byte gender;
    private String departmentName;
    private String professionName;
    private String className;
    private Date reportTime;
    private String idNo;
    private String phone;
    private String phoneMac;
    private String dorm;
    private int admissionYear;
    private String politic;
    private int status;
    private String reportDate;
    private String operationLog;

    public void setClassName(String className) {
        this.className = className;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getIdNo() {
        return this.idNo;
    }

    public String getPhone() {
        return this.phone;
    }

    public String getPhoneMac() {
        return this.phoneMac;
    }

    public void setIdNo(String idNo) {
        this.idNo = idNo;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public void setPhoneMac(String phoneMac) {
        this.phoneMac = phoneMac;
    }

    public void setProfessionName(String professionName) {
        this.professionName = professionName;
    }

    public String getProfessionName() {
        return this.professionName;
    }

    public String getDepartmentName() {
        return this.departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public void setGender(Byte gender) {
        this.gender = gender;
    }

    public String getOperationLog() {
        return this.operationLog;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public void setOperationLog(String operationLog) {
        this.operationLog = operationLog;
    }

    public void setReportDate(String reportDate) {
        this.reportDate = reportDate;
    }

    public String getAlarmName() {
        return this.alarmName;
    }

    public String getSno() {
        return this.sno;
    }

    public Date getReportTime() {
        return this.reportTime;
    }

    public int getStatus() {
        return this.status;
    }

    public String getReportDate() {
        return this.reportDate;
    }

    public void setReportTime(Date reportTime) {
        this.reportTime = reportTime;
    }

    public void setSno(String sno) {
        this.sno = sno;
    }

    public Byte getGender() {
        return this.gender;
    }

    public String getDorm() {
        return this.dorm;
    }

    public void setDorm(String dorm) {
        this.dorm = dorm;
    }

    public void setAdmissionYear(int admissionYear) {
        this.admissionYear = admissionYear;
    }

    public String getPolitic() {
        return this.politic;
    }

    public void setPolitic(String politic) {
        this.politic = politic;
    }

    public void setAlarmName(String alarmName) {
        this.alarmName = alarmName;
    }

    public int getAdmissionYear() {
        return this.admissionYear;
    }

    public String toString() {
        return "ActiveAlarm{id=" + this.id + ", alarmName='" + this.alarmName + '\'' + ", sno='" + this.sno + '\'' + ", name='" + this.name + '\'' + ", gender=" + this.gender + ", departmentName='" + this.departmentName + '\'' + ", professionName='" + this.professionName + '\'' + ", className='" + this.className + '\'' + ", reportTime=" + this.reportTime + ", idNo='" + this.idNo + '\'' + ", phone='" + this.phone + '\'' + ", phoneMac='" + this.phoneMac + '\'' + ", dorm='" + this.dorm + '\'' + ", admissionYear=" + this.admissionYear + ", politic='" + this.politic + '\'' + ", status=" + this.status + ", reportDate='" + this.reportDate + '\'' + ", operationLog='" + this.operationLog + '\'' + '}';
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return this.id;
    }

    public String getClassName() {
        return this.className;
    }
}

Affect(row-cnt:2) cost in 350 ms.

4.4.Watch

4.4.1監控返回值

$ watch com.gbcom.gidata.alarm.controller.ActiveAlarmController findByPage returnObj 
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 361 ms.
ts=2019-07-29 14:46:08; [cost=1677.776414ms] result=@ResultVO[
    code=@Integer[200],
    msg=@String[操作成功],
    data=@PageImpl[Page 1 of 48 containing com.gbcom.gidata.alarm.entity.primary.ActiveAlarm instances],
]
ts=2019-07-29 14:46:08; [cost=1848.329463ms] result=@ResultVO[
    code=@Integer[200],
    msg=@String[操作成功],
    data=@PageImpl[Page 1 of 48 containing com.gbcom.gidata.alarm.entity.primary.ActiveAlarm instances],
]

4.4.2監控參數
監控所有參數

$ watch com.gbcom.gidata.alarm.controller.ActiveAlarmController findByPage params
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 231 ms.
ts=2019-07-29 14:47:28; [cost=42.880745ms] result=@Object[][
    @AlarmDto[AlarmDto [pageNumber=1, pageSize=10, date=null, alamName=null, num=null, idNo=null, phone=null, phoneMac=null]],
]
ts=2019-07-29 14:47:28; [cost=50.596983ms] result=@Object[][
    @AlarmDto[AlarmDto [pageNumber=1, pageSize=10, date=null, alamName=null, num=null, idNo=null, phone=null, phoneMac=null]],
]

監控指定參數的某一個值

$ watch com.gbcom.gidata.alarm.controller.ActiveAlarmController findByPage params[0].pageSize
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 214 ms.
ts=2019-07-29 14:48:40; [cost=28.2795ms] result=@Integer[10]
ts=2019-07-29 14:48:40; [cost=77.127107ms] result=@Integer[10]

4.4.3監控異常

$ watch com.gbcom.gidata.alarm.controller.ActiveAlarmController findByPage throwExp 
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 167 ms.
ts=2019-07-29 14:51:21; [cost=13.121286ms] result=null
ts=2019-07-29 14:51:21; [cost=18.437713ms] result=null

result=null無異常

4.5退出arthas

如果只是退出當前的連接,可以用quit或者exit命令。Attach到目標進程上的arthas還會繼續運行,端口會保持開放,下次連接時可以直接連接上。
如果想完全退出arthas,可以執行shutdown命令。

5日誌

5.1執行結果存日誌
將命令的結果完整保存在日誌文件中,便於後續進行分析
默認情況下,該功能是關閉的,如果需要開啓,請執行以下命令:

$ options save-result true
 NAME         BEFORE-VALUE  AFTER-VALUE
----------------------------------------
 save-result  false         true
Affect(row-cnt:1) cost in 3 ms.

看到上面的輸出,即表示成功開啓該功能;
日誌文件路徑
結果會異步保存在:{user.home}/logs/arthas-cache/result.log,請定期進行清理,以免佔據磁盤空間
5.2使用新版本Arthas的異步後臺任務將結果存日誌文件

$ trace Test t >>  &
job id  : 2
cache location  : /Users/admin/logs/arthas-cache/28198/2

此時命令會在後臺異步執行,並將結果異步保存在文件(~/logs/arthas-cache/PID/{PID}/{JobId})中;
此時任務的執行不受session斷開的影響;任務默認超時時間是1天,可以通過全局 options 命令修改默認超時時間;
此命令的結果將異步輸出到文件中;此時不管 save-result 是否爲true,都不會再往~/logs/arthas-cache/result.log 中異步寫結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章