天天看點

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程序:

[[email protected] 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:                                                                                                                                                                                                                                     
[email protected]e                                                                                                                                                                                
  [email protected]                                                                                                                                                                                                     
    [email protected]                                                                                                                                                                                                  

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] [email protected][
    [email protected][200],
    [email protected][操作成功],
    [email protected][Page 1 of 48 containing com.gbcom.gidata.alarm.entity.primary.ActiveAlarm instances],
]
ts=2019-07-29 14:46:08; [cost=1848.329463ms] [email protected][
    [email protected][200],
    [email protected][操作成功],
    [email protected][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] [email protected][][
    @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] [email protected][][
    @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] [email protected][10]
ts=2019-07-29 14:48:40; [cost=77.127107ms] [email protected][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/ P I D / {PID}/ PID/{JobId})中;

此時任務的執行不受session斷開的影響;任務預設逾時時間是1天,可以通過全局 options 指令修改預設逾時時間;

此指令的結果将異步輸出到檔案中;此時不管 save-result 是否為true,都不會再往~/logs/arthas-cache/result.log 中異步寫結果