jvm調優神器alsace(阿爾薩斯)安裝與調優介紹

1alsace(阿爾薩斯)安裝

alsace官網鏈接:官網鏈接
安裝方式分爲兩種
1).自動安裝步驟
1.1快速安裝
使用arthas-boot(推薦)

1步 curl -O https://alibaba.github.io/arthas/arthas-boot.jar
第2步  java -jar arthas-boot.jar

注,如果沒有java程序,運行第二步會報錯,需要啓動一個java進程;
啓動後退出 按Q就退出了
1.2使用as.sh
Arthas 支持在 Linux/Unix/Mac 等平臺上一鍵安裝,請複製以下內容,並粘貼到命令行中,敲 回車 執行即可:

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

2.手動安裝步驟
手動安裝Arthas
下載最新版本

最新版本,點擊下載:https://img.shields.io/maven-central/v/com.taobao.arthas/arthas-packaging.svg?style=flat-square

如果下載速度比較慢,可以嘗試用阿里雲的鏡像倉庫,比如要下載3.x.x版本(替換3.x.x爲最新版本),下載的url是:

https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/3.x.x/arthas-packaging-3.x.x-bin.zip

解壓縮arthas的壓縮包

unzip arthas-packaging-bin.zip

安裝Arthas

安裝之前最好把所有老版本的Arthas全都刪掉

sudo su admin
rm -rf /home/admin/.arthas/lib/*
cd arthas
./install-local.sh

注意,這裏根據你需要診斷的Java進程的所屬用戶進行切換

啓動Arthas

啓動之前,請確保老版本的Arthas已經stop.

./as.sh

2alsace調優介紹

2.1快速入門
快速入門

  1. 啓動Demo
curl -O https://alibaba.github.io/arthas/arthas-demo.jar
java -jar arthas-demo.jar

arthas-demo是一個簡單的程序,每隔一秒生成一個隨機數,再執行質因數分解,並打印出分解結果。

arthas-demo源代碼:查看

  1. 啓動arthas
    在命令行下面執行(使用和目標進程一致的用戶啓動,否則可能attach失敗):
curl -O 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進程:

$ $ java -jar arthas-boot.jar
* [1]: 35542
  [2]: 71560 arthas-demo.jar

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

[INFO] Try to attach process 71560
[INFO] Attach process 71560 success.
[INFO] arthas-client connect 127.0.0.1 3658
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
 
wiki: https://alibaba.github.io/arthas
version: 3.0.5.20181127201536
pid: 71560
time: 2018-11-28 19:16:24

$
3. 查看dashboard
輸入dashboard,按回車/enter,會展示當前進程的信息,按ctrl+c可以中斷執行。

$ dashboard
ID     NAME                   GROUP          PRIORI STATE  %CPU    TIME   INTERRU DAEMON
17     pool-2-thread-1        system         5      WAITIN 67      0:0    false   false
27     Timer-for-arthas-dashb system         10     RUNNAB 32      0:0    false   true
11     AsyncAppender-Worker-a system         9      WAITIN 0       0:0    false   true
9      Attach Listener        system         9      RUNNAB 0       0:0    false   true
3      Finalizer              system         8      WAITIN 0       0:0    false   true
2      Reference Handler      system         10     WAITIN 0       0:0    false   true
4      Signal Dispatcher      system         9      RUNNAB 0       0:0    false   true
26     as-command-execute-dae system         10     TIMED_ 0       0:0    false   true
13     job-timeout            system         9      TIMED_ 0       0:0    false   true
1      main                   main           5      TIMED_ 0       0:0    false   false
14     nioEventLoopGroup-2-1  system         10     RUNNAB 0       0:0    false   false
18     nioEventLoopGroup-2-2  system         10     RUNNAB 0       0:0    false   false
23     nioEventLoopGroup-2-3  system         10     RUNNAB 0       0:0    false   false
15     nioEventLoopGroup-3-1  system         10     RUNNAB 0       0:0    false   false
Memory             used   total max    usage GC
heap               32M    155M  1820M  1.77% gc.ps_scavenge.count  4
ps_eden_space      14M    65M   672M   2.21% gc.ps_scavenge.time(m 166
ps_survivor_space  4M     5M    5M           s)
ps_old_gen         12M    85M   1365M  0.91% gc.ps_marksweep.count 0
nonheap            20M    23M   -1           gc.ps_marksweep.time( 0
code_cache         3M     5M    240M   1.32% ms)
Runtime
os.name                Mac OS X
os.version             10.13.4
java.version           1.8.0_162
java.home              /Library/Java/JavaVir
                       tualMachines/jdk1.8.0
                       _162.jdk/Contents/Hom
                       e/jre

dashboard命令示意圖

  1. 通過thread(線程相關)命令來獲取到arthas-demo進程的Main Class
    只輸入 thread 會輸出當前進程的所有線程
    thread 1會打印線程ID 1的棧,通常是main函數的線程。

thread的參數: -n N(數量) 表示 指定最忙的前N個線程並打印堆棧
-b 找出當前阻塞其他線程的線程
i 指定cpu佔比統計的採樣間隔,單位爲毫秒
查看某狀態的線程 thread --state 狀態 等待狀態的 thread --state WAITING

$ thread 1 | grep 'main('
    at demo.MathGame.main(MathGame.java:17)
$ thread 1 
 'main('
    at demo.MathGame.main(MathGame.java:17)
  1. 通過jad來反編譯Main Class
$ jad demo.MathGame
$ jad demo.MathGame

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@3d4eac69
  +-sun.misc.Launcher$ExtClassLoader@66350f69
 
Location:
/tmp/arthas-demo.jar
 
/*
 * Decompiled with CFR 0_132.
 */
package demo;
 
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
 
public class MathGame {
    private static Random random = new Random();
    private int illegalArgumentCount = 0;
 
    public static void main(String[] args) throws InterruptedException {
        MathGame game = new MathGame();
        do {
            game.run();
            TimeUnit.SECONDS.sleep(1L);
        } while (true);
    }
 
    public void run() throws InterruptedException {
        try {
            int number = random.nextInt();
            List<Integer> primeFactors = this.primeFactors(number);
            MathGame.print(number, primeFactors);
        }
        catch (Exception e) {
            System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage());
        }
    }
 
    public static void print(int number, List<Integer> primeFactors) {
        StringBuffer sb = new StringBuffer("" + number + "=");
        Iterator<Integer> iterator = primeFactors.iterator();
        while (iterator.hasNext()) {
            int factor = iterator.next();
            sb.append(factor).append('*');
        }
        if (sb.charAt(sb.length() - 1) == '*') {
            sb.deleteCharAt(sb.length() - 1);
        }
        System.out.println(sb);
    }
 
    public List<Integer> primeFactors(int number) {
        if (number < 2) {
            ++this.illegalArgumentCount;
            throw new IllegalArgumentException("number is: " + number + ", need >= 2");
        }
        ArrayList<Integer> result = new ArrayList<Integer>();
        int i = 2;
        while (i <= number) {
            if (number % i == 0) {
                result.add(i);
                number /= i;
                i = 2;
                continue;
            }
            ++i;
        }
        return result;
    }
}
 
Affect(row-cnt:1) cost in 970 ms.
  1. watch 監視
通過watch命令來查看demo.MathGame#primeFactors函數的返回值:

語法: watch 包名.類名 類的方法 類的返回值
$ watch demo.MathGame primeFactors returnObj

$ watch demo.MathGame primeFactors returnObj
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 107 ms.
ts=2018-11-28 19:22:30; [cost=1.715367ms] result=null
ts=2018-11-28 19:22:31; [cost=0.185203ms] result=null
ts=2018-11-28 19:22:32; [cost=19.012416ms] result=@ArrayList[
    @Integer[5],
    @Integer[47],
    @Integer[2675531],
]
ts=2018-11-28 19:22:33; [cost=0.311395ms] result=@ArrayList[
    @Integer[2],
    @Integer[5],
    @Integer[317],
    @Integer[503],
    @Integer[887],
]
ts=2018-11-28 19:22:34; [cost=10.136007ms] result=@ArrayList[
    @Integer[2],
    @Integer[2],
    @Integer[3],
    @Integer[3],
    @Integer[31],
    @Integer[717593],
]
ts=2018-11-28 19:22:35; [cost=29.969732ms] result=@ArrayList[
    @Integer[5],
    @Integer[29],
    @Integer[7651739],
]

更多的功能可以查看進階使用。

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

如果想完全退出arthas,可以執行stop命令。

  1. 基礎命令

help——查看命令幫助信息

cat——打印文件內容,和linux裏的cat命令類似

echo–打印參數,和linux裏的echo命令類似

grep——匹配查找,和linux裏的grep命令類似

tee——複製標準輸入到標準輸出和指定的文件,和linux裏的tee命令類似

pwd——返回當前的工作目錄,和linux命令類似

cls——清空當前屏幕區域

session——查看當前會話的信息

reset——重置增強類,將被 Arthas 增強過的類全部還原,Arthas 服務端關閉時會重置所有增強過的類

version——輸出當前目標 Java 進程所加載的 Arthas 版本號

history——打印命令歷史

quit——退出當前 Arthas 客戶端,其他 Arthas 客戶端不受影響

stop——關閉 Arthas 服務端,所有 Arthas 客戶端全部退出

keymap——Arthas快捷鍵列表及自定義快捷鍵

jvm相關

dashboard——當前系統的實時數據面板

thread——查看當前 JVM 的線程堆棧信息
thread的參數: -n N(數量) 表示 指定最忙的前N個線程並打印堆棧
b 找出當前阻塞其他線程的線程
i 指定cpu佔比統計的採樣間隔,單位爲毫秒
jvm——查看當前 JVM 的信息

sysprop——查看和修改JVM的系統屬性

sysenv——查看JVM的環境變量

vmoption——查看和修改JVM裏診斷相關的option

perfcounter——查看當前 JVM 的Perf Counter信息

logger——查看和修改logger

getstatic——查看類的靜態屬性

ognl——執行ognl表達式

mbean——查看 Mbean 的信息

heapdump——dump java heap, 類似jmap命令的heap dump功能

class/classloader相關

sc(Search-Class)——查看JVM已加載的類信息Search-Class

sm(Search-Method)——查看已加載類的方法信息

jad——反編譯指定已加載類的源碼

mc——內存編譯器,內存編譯.java文件爲.class文件

redefine——加載外部的.class文件,redefine到JVM裏

dump——dump 已加載類的 byte code 到特定目錄

classloader——查看classloader的繼承樹,urls,類加載信息,使用classloader去getResource

monitor/watch/trace相關

請注意,這些命令,都通過字節碼增強技術來實現的,會在指定類的方法中插入一些切面來實現數據統計和觀測,因此在線上、預發使用時,請儘量明確需要觀測的類、方法以及條件,診斷結束要執行
stop 或將增強過的類執行 reset 命令。

monitor——方法執行監控

watch——方法執行數據觀測

trace——方法內部調用路徑,並輸出方法路徑上的每個節點上耗時

stack——輸出當前方法被調用的調用路徑

tt——方法執行數據的時空隧道,記錄下指定方法每次調用的入參和返回信息,並能對這些不同的時間下調用進行觀測

profiler/火焰圖 profiler–使用async-profiler對應用採樣,生成火焰圖

options options——查看或設置Arthas全局開關

管道 Arthas支持使用管道對上述命令的結果進行進一步的處理,如sm java.lang.String * | grep ‘index’

grep——搜索滿足條件的結果

plaintext——將命令的結果去除ANSI顏色

wc——按行統計輸出結果

後臺異步任務 當線上出現偶發的問題,比如需要watch某個條件,而這個條件一天可能纔會出現一次時,異步後臺任務就派上用場了,詳情請參考這裏

使用 > 將結果重寫向到日誌文件,使用 & 指定命令是後臺運行,session斷開不影響任務執行(生命週期默認爲1天)

jobs——列出所有job

kill——強制終止任務

fg——將暫停的任務拉到前臺執行

bg——將暫停的任務放到後臺執行

Web Console 通過websocket連接Arthas。

Web Console 以java agent方式啓動 以java agent方式啓動 用戶數據回報
在3.1.4版本後,增加了用戶數據回報功能,方便統一做安全或者歷史數據統計。

在啓動時,指定stat-url,就會回報執行的每一行命令,比如: ./as.sh --stat-url
‘http://192.168.10.11:8080/api/stat’

在tunnel server裏有一個示例的回報代碼,用戶可以自己在服務器上實現。

StatController.java

官方命令列表地址添加鏈接描述

6遠程連接alsace

通過瀏覽器連接arthas
連接教程地址添加鏈接描述

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