日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

Arthas 是Alibaba開源的JAVA診斷工具,深受開發者喜愛。

當你遇到以下類似問題而束手無策時,Arthas可以幫助你解決:

  1. 這個類從哪個 jar 包加載的?為什么會報各種類相關的 Exception?
  2. 我改的代碼為什么沒有執行到?難道是我沒 commit?分支搞錯了?
  3. 遇到問題無法在線上 debug,難道只能通過加日志再重新發布嗎?
  4. 線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!
  5. 是否有一個全局視角來查看系統的運行狀況?
  6. 有什么辦法可以監控到JVM的實時運行狀態?
  7. 怎么快速定位應用的熱點,生成火焰圖?
  8. 怎樣直接從JVM內查找某個類的實例?

這 8 個問題,Arthas 官方文檔(https://arthas.aliyun.com/doc)中并沒有給出答案或標準的解決方案。

坑爹啊

這不是管殺不管埋嗎??!

準備

先給出我的測試代碼

package com.admin.study;

import com.alibaba.fastjson.JSON;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.FieldDefaults;

import java.util.List;
import java.util.concurrent.TimeUnit;

public class ArthasDemo {
    public static void main(String[] args) {
        String s = "[{"name":"zhangsan","age":"10","telephone":"123456","interests":["sing","dance","rap"]},n" +
                "{"name":"lisi","age":"20","telephone":"123457","interests":["sing","swim"]},n" +
                "{"name":"wangwu","age":"30","telephone":"123458","interests":["sing","program"]}]";
        //模擬一遍遍的調用方法的過程
        for (; ; ) {
            System.out.println(new ArthasDemo().convert(s));
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private List<People> convert(String s) {
        return JSON.parseArray(s, People.class);
    }


    @Getter
    @Setter
    @ToString
    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class People {
        /**
         * 姓名
         */
        String name;
        /**
         * 年齡
         */
        String age;
        /**
         * 電話
         */
        String telephone;
        /**
         * 興趣列表
         */
        List<String> interests;
    }
}

以下是控制臺正常打印的結果

/Library/Java/JavaVirtualmachines/jdk1.8.0_192.jdk/Contents/Home/bin/java ...
[ArthasDemo.People(name=zhangsan, age=10, telephone=123456, interests=[sing, dance, rap]), ArthasDemo.People(name=lisi, age=20, telephone=123457, interests=[sing, swim]), ArthasDemo.People(name=wangwu, age=30, telephone=123458, interests=[sing, program])]
[ArthasDemo.People(name=zhangsan, age=10, telephone=123456, interests=[sing, dance, rap]), ArthasDemo.People(name=lisi, age=20, telephone=123457, interests=[sing, swim]), ArthasDemo.People(name=wangwu, age=30, telephone=123458, interests=[sing, program])]

下載并運行 Arthas

按照下圖中的步驟,選擇一個 Java 進程進行 attach。

帶著8個問題5分鐘教你學會Arthas診斷工具

 

下載并運行Arthas

訪問 WebConsole

attach 成功后可以打開谷歌瀏覽器輸入http://127.0.0.1:3658/ 打開 WebConsole

(吐槽一句 Mac OS 的 Safari 瀏覽器不支持)

?

使用 WebConsole 最方便的是你可以打開多個標簽頁同時操作

?

問題 1:這個類從哪個 jar 包加載的?為什么會報各種類相關的 Exception?

這個問題我經常在處理各種「依賴沖突」的時候遇到,有一些類的完全名稱是一模一樣,通過常規的辦法無法解決類具體從哪個 jar 包加載。

別急,看我下面的解決辦法。

  1. sc

通過 sc 命令 模糊查看當前 JVM 中是否加載了包含關鍵字的類,以及獲取其完全名稱。

?

注意使用 sc -d 命令,獲取 classLoaderHash,這個值在后面需要用到。

?

sc -d *ArthasDemo*
帶著8個問題5分鐘教你學會Arthas診斷工具

 

sc-d命令

  1. classloader

通過 classloader 查看 class 文件來自哪個 jar 包

?

使用 cls 命令可以清空命令行,這個簡單的命令官方文檔居然找不到。。。

?

?

注意 classloader -c 后面的值填上面第一步中獲取到的 Hash 值,class 文件路徑使用'/'分割,且必須以.class 結尾。

?

[arthas@3633]$ classloader -c 18b4aac2 -r com/admin/study/ArthasDemo.class
file:/Users/admin/code/concurrentbook/target/classes/com/shockang/study/ArthasDemo.class
Affect(row-cnt:1) cost in 0 ms.

上面是顯示 class 文件路徑的,如果 class 文件來自 jar 包,可以顯示 jar 包路徑,例如官方文檔給的例子:

$ classloader -c 1b6d3586 -r java/lang/String.class
jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/String.class

問題 2:我改的代碼為什么沒有執行到?難道是我沒 commit?分支搞錯了?

推薦使用 watch 和 tt 命令,非常好用。

這兩個命令都是用來查看方法調用過程的,不同的是 watch 命令是調用一次打印一次方法的調用情況,而 tt 命令可以先生成一個不斷增加的調用列表,然后指定其中某一項進行觀測。

  1. 使用 watch 命令查看方法調用情況。我們要查看 ArthasDemo 這個類里面的 convert 方法調用情況。
帶著8個問題5分鐘教你學會Arthas診斷工具

 

watch命令

watch com.shockang.study.ArthasDemo convert "{params,target,returnObj}" -f -x 4

watch 后面跟上完全類名和方法名,以及一個 OGNL 的表達式,-f 表示不論正常返回還是異常返回都進行觀察,-x 表示輸出結果的屬性遍歷深度,默認為 1,

?

建議無腦寫 4 就行,這是筆者經驗來看最大的遍歷深度,再大就不支持了

?

  1. 使用 tt 命令來觀測方法調用情況,tt 命令可以查看「多次調用」并選擇其中一個進行觀測,但是如果輸出結果是多層嵌套就沒辦法看了,而 watch 可以查看「多層嵌套」的結果。

?

使用 tt -t 記錄下當前方法的每次調用環境現場

?

帶著8個問題5分鐘教你學會Arthas診斷工具

 

tt -t命令

tt -t com.shockang.study.ArthasDemo convert

TIMESTAMP表示方法調用發生的時間,COST 表示調用耗時(ms),IS-RET表示是否正常返回,IS-EXP 表示是否異常返回,OBJECT 表示對象的 HASH 值

?

對于具體一個時間片的信息而言,你可以通過 -i 參數后邊跟著對應的 INDEX 編號查看到他的詳細信息

?

 

帶著8個問題5分鐘教你學會Arthas診斷工具

 

tt-i命令

?

圖中之所以可以打印興趣列表,是調用了其 toString 方法,如果沒有重寫 java.lang.Object 類的 toString 方法,只會看到 hash 值。

?

  1. 如何判斷代碼是否已經提交?

通過 jad --source-only 可以查看源代碼。

[arthas@3633]$ jad --source-only com.admin.study.ArthasDemo
       /*
        * Decompiled with CFR.
        */
       package com.admin.study;

       import com.alibaba.fastjson.JSON;
       import java.util.List;
       import java.util.concurrent.TimeUnit;

       public class ArthasDemo {
           public static void main(String[] args) {
/*15*/         String s = "[{"name":"zhangsan","age":"10","telephone":"123456","interests":["sing","dance","rap"]},n{"name":"lisi","age":"20
","telephone":"123457","interests":["sing","swim"]},n{"name":"wangwu","age":"30","telephone":"123458","interests":["sing","program"]}]";
               while (true) {
/*20*/             System.out.println(new ArthasDemo().convert(s));
                   try {
/*22*/                 TimeUnit.SECONDS.sleep(10L);
/*25*/                 continue;
                   }
                   catch (InterruptedException e) {
/*24*/                 e.printStackTrace();
                       continue;
                   }
                   break;
               }
           }

           private List<People> convert(String s) {
/*30*/         return JSON.parseArray(s, People.class);
           }

           private static class People {
               private String name;
               private String age;
               private String telephone;
               private List<String> interests;

               private People() {
               }

               public String toString() {
                   return "ArthasDemo.People(name=" + this.getName() + ", age=" + this.getAge() + ", telephone=" + this.getTelephone() + ", interests=" + this.getIntere
sts() + ")";
               }

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

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

               public String getAge() {
                   return this.age;
               }

               public String getTelephone() {
                   return this.telephone;
               }

               public List<String> getInterests() {
                   return this.interests;
               }

               public void setAge(String age) {
                   this.age = age;
               }

               public void setTelephone(String telephone) {
                   this.telephone = telephone;
               }

               public void setInterests(List<String> interests) {
                   this.interests = interests;
               }
           }
       }

[arthas@3633]$

問題 3:遇到問題無法在線上 debug,難道只能通過加日志再重新發布嗎?

通過上面問題 2 的 watch 和 tt 命令可以查看方法調用情況。

此外,可以通過 redefine 命令「熱替換」線上的代碼,注意應用重啟之后會失效,這在某些緊急情況下會有奇效。

比如說我們修改一下方法體里面的代碼,加了一行日志打?。?/p>

    private List<People> convert(String s) {
        System.out.println(s);
        return JSON.parseArray(s, People.class);
    }

這時我們就可以將新代碼編譯后的 class 文件熱替換正在運行的 ArthasDemo 的代碼。

帶著8個問題5分鐘教你學會Arthas診斷工具

 

redefine命令

帶著8個問題5分鐘教你學會Arthas診斷工具

 

 

熱替換 JVM 內存中(方法區)加載的類

從這張圖可以明顯的看出,明明源碼中沒有打印字符串 s 的邏輯,但是控制臺還是打印了字符串,因為我們已經熱替換了 JVM 內存中(方法區)加載的類。

問題 4:線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!

這個問題沒有完美的解決辦法

參考一下問題 2 和問題 3的解決方案

推薦使用 tt 命令并將命令行返回結果輸出到一個文件中,后續可以選擇異常的一行記錄使用 tt -i 命令進行深入的分析。

tee指令會從標準輸入設備讀取數據,將其內容輸出到標準輸出設備,同時保存成文件。

帶著8個問題5分鐘教你學會Arthas診斷工具

 

tee命令

tt -t com.admin.study.ArthasDemo convert | tee /Users/admin/Downloads/log

此外還可以使用 monitor 命令統計方法調用成功失敗情況。

帶著8個問題5分鐘教你學會Arthas診斷工具

 

monitor命令

monitor -c 30 com.admin.study.ArthasDemo convert | tee /Users/admin/Downloads/log1

?

-c 后面接統計周期,默認值為120秒

?

問題 5:是否有一個全局視角來查看系統的運行狀況?

使用 dashboard 命令可以查看當前系統的實時數據面板, 當運行在Ali-Tomcat時,會顯示當前tomcat的實時信息,如HTTP請求的qps, rt, 錯誤數, 線程池信息等等。

帶著8個問題5分鐘教你學會Arthas診斷工具

 

dashboard實時數據面板

從圖中可以看到線程情況,內存使用情況,系統參數等。

問題 6:有什么辦法可以監控到JVM的實時運行狀態?

使用 jvm 命令可以查看 JVM 的實時運行狀態。

帶著8個問題5分鐘教你學會Arthas診斷工具

 

JVM 的實時運行狀態

問題 7:怎么快速定位應用的熱點,生成火焰圖?

profiler 命令支持生成應用熱點的火焰圖。本質上是通過不斷的采樣,然后把收集到的采樣結果生成火焰圖。

?

默認情況下,生成的是 cpu 的火焰圖,即 event 是 cpu,可以用--event 參數來指定。注意不同系統支持的 event 不同

?

 

帶著8個問題5分鐘教你學會Arthas診斷工具

 

默認情況下,arthas使用3658端口,則可以打開:http://localhost:3658/arthas-output/ 查看到arthas-output目錄下面的profiler結果:

帶著8個問題5分鐘教你學會Arthas診斷工具

 

profiler目錄

選擇一項點擊

帶著8個問題5分鐘教你學會Arthas診斷工具

 

profiler結果圖

問題 8:怎樣直接從JVM內查找某個類的實例?

使用 vmtool 可以達成目的

?

這個功能是 Arthas 3.5.1 新增的。可以參考官方文檔 https://arthas.aliyun.com/doc/vmtool.html#id1

?

$ vmtool --action getInstances --className java.lang.String --limit 10
@String[][
    @String[com/taobao/arthas/core/shell/session/Session],
    @String[com.taobao.arthas.core.shell.session.Session],
    @String[com/taobao/arthas/core/shell/session/Session],
    @String[com/taobao/arthas/core/shell/session/Session],
    @String[com/taobao/arthas/core/shell/session/Session.class],
    @String[com/taobao/arthas/core/shell/session/Session.class],
    @String[com/taobao/arthas/core/shell/session/Session.class],
    @String[com/],
    @String[java/util/concurrent/ConcurrentHashMap$ValueIterator],
    @String[java/util/concurrent/locks/LockSupport],
]

通過 --limit參數,可以限制返回值數量,避免獲取超大數據時對JVM造成壓力。默認值是10。

如果想精確的定位到具體的類實例,可以通過指定 classloader name 或者 classloader hash,如下所示:

vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext
vmtool --action getInstances -c 19469ea2 --className org.springframework.context.ApplicationContext

?

獲取 classloader hash 的方法請參考上面的問題 1

?

vmtool 還有個不錯的功能,可以「強制進行GC」,這在某些生產環境內存緊張的情況下有奇效。

vmtool --action forceGc

分享到:
標簽:Arthas
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定