自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

簡明的 Arthas 配置及基礎運維教程

開發(fā) 開源
Arthas是一款強大的開源Java診斷程序,它可以非常方便的啟動并以界面式的方式和Java程序進行交互,支持監(jiān)控程序的內(nèi)存使用情況、線程信息、gc情況、甚至可以反編譯并修改現(xiàn)上代碼等。

Arthas是一款強大的開源Java診斷程序,它可以非常方便的啟動并以界面式的方式和Java程序進行交互,支持監(jiān)控程序的內(nèi)存使用情況、線程信息、gc情況、甚至可以反編譯并修改現(xiàn)上代碼等。

一、簡述Arthas的運行原理(理解)

arthas的運行原理大致是以下幾個步驟:

  • 啟動arthas選擇目標Java程序后,artahs會向目標程序注入一個代理。
  • 代理會創(chuàng)建一個集HTTP和Telnet的服務器與客戶端建立連接。
  • 客戶端與服務端建立連接。
  • 后續(xù)客戶端需要監(jiān)控或者調(diào)整程序都可以通過服務端Java Instrumentation機制和應用程序產(chǎn)生交互。

二、詳解Arthas基礎使用

1.下載安裝

在介紹幾個典型的案例之前,我們需要先下載安裝一下Arthas,Arthas的官方地址如下:

Arthas的官方地址:https://arthas.aliyun.com/

考慮到方便筆者一般是使用命令行的方式下載:

curl -O https://arthas.aliyun.com/arthas-boot.jar

完成后我們通過下面這個命令就可以將Arthas啟動了。

java -jar arthas-boot.jar

此時我們就可以看到對應的進程序號和進程的pid,以筆者為例,開啟arthas之后就會看到一個序號為1的9121的Java進程,我們可以直接點擊1并輸入回車對此進程進行監(jiān)控管理:

[INFO] JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64/jre
[INFO] arthas-boot version: 3.7.2
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 9121 arthasExample.jar

隨后arthas初次會進行相關依賴下載,然后我們就可以正式的使用arthas管理當前進程了:

2.離線用戶的使用姿勢(可選閱讀)

考慮到內(nèi)網(wǎng)用戶無法聯(lián)網(wǎng)進行arthas初始化,所以arthas也人性化的提供了全量包的下載方式,有需要的讀者可移步到下載頁面選擇全量包下載即可獲取全量的arthas包:

完成后下載并解壓之后,我們可以直接通過下面這個腳本指令快速啟動arthas:

./as.sh

3.常見指令介紹

步入arthas我們就可以進行一些比較基礎的操作,以下是筆者日常用的比較多的指令,和Linux差不多,讀者可自行參閱了解

  • cat:打印文件內(nèi)容。
  • cls:清空當前屏幕區(qū)域內(nèi)容。
  • grep:匹配查找。
  • history:打印歷史命令。
  • pwd:輸入當前Java進程所在的位置。
  • quit:退出當前arthas客戶端。
  • stop:關閉arthas服務端,所有arthas客戶端都會退出。

這里筆者就簡單的演示一下,可以看到pwd輸出的就是筆者所監(jiān)控的Java進程所處的文件目錄:

[arthas@9121]$ pwd
# 當前監(jiān)控的進程在服務器上的目錄
/home/sharkchili/arthasExample
[arthas@9121]$

又比如筆者通過memory查看堆內(nèi)存使用情況,如果只想看老年代的數(shù)據(jù),就可以使用grep:

memory |grep ps_old_gen

點擊quit會直接退出當前進程的客戶端,stop同理只不過多是連著服務端和其他客戶端一并殺掉,這里就不多做演示了:

[arthas@9121]$ quit
# 直接返回到服務器的目錄
sharkchili@DESKTOP-7IPKPVJ:~/arthas$

4.快捷啟動配置

為了快捷啟動arthas,筆者也給出個人的配置方式,首先vim一個名為as.sh的腳本,其內(nèi)容為arthas-boot.jar的啟動指令:

java -jar /home/sharkchili/arthas/arthas-boot.jar

完成腳本編寫確認啟動無誤之后,我們將這個腳本通過alias重命名的方式追加到/etc/profile下,內(nèi)容如下即sh指令加上上述腳本的全路徑:

alias as="sh /home/sharkchili/arthas/as.sh"

然后通過source指令使其生效:

可以看到完成這樣一段配直接后,我們可以直接通過as指令完成arthas的快捷啟動:

# 鍵入as
sharkchili@DESKTOP-xxx:~$ as
# 直接快速啟動arthas
[INFO] JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64/jre
[INFO] arthas-boot version: 3.7.2
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 9121 arthasExample.jar

三、Arthas中比較常用的運維指令

1.查看實時數(shù)據(jù)面板

日常開發(fā)維護過程中對于項目的巡檢還是蠻重要的,通過Arthas的dashboard可以非常直觀的查看當前系統(tǒng)中進程的運行情況。

在arthas的控制面板輸入dashboard,默認情況下5s進行一次刷新:

這里我們來簡單介紹一下第一板塊線程中的字段的含義:

  • ID:java級別的線程id號,注意與jstack中的native id的區(qū)別。
  • NAME:線程名稱。
  • GROUP:線程所在線程組名。
  • PRIORITY:線程優(yōu)先級,值越大優(yōu)先級越高。
  • STATE:線程運行狀態(tài)。
  • CPU%:線程CPU使用率。
  • DELTA_TIME:上次采樣之后,線程運行的CPU時間,單位為秒。
  • TIME:線程運行的總CPU時長,數(shù)據(jù)格式為分:秒。
  • INTERRUPTED:線程當前的中斷位狀態(tài)。
  • DAEMON :是否為守護線程。

第二板塊就是內(nèi)存使用版塊,記錄各個堆區(qū)、元空間的內(nèi)存使用情況以及GC情況。而第三板塊則是服務器運行參數(shù)版塊,這一版塊記錄著程序當前運行服務器的內(nèi)核版本信息、jdk版本等。

需要了解的是arthas中的操作指令可以通過--help了解查閱,我們以dashboard為例,其使用說明如下,可以看到我們可以通過-i決定面板刷新間隔(單位是毫秒),用-n決定面板刷新次數(shù):

所以如果我們希望每1s刷新1次,刷新5次,那么對應的命令就是:

dashboard -i 1000 -n 5

2.查看JVM信息

arthas也可能非常直觀的查看jvm信息,對應的指令也就是jvm。

同樣的這個指令也會輸出多個板塊的內(nèi)容,我們先來看看第一個板塊,可以可以看到該指令可以非常直觀的看到機器名稱、jvm啟動時間、jdk版本以及我們配置jvm參數(shù)信息:

由于板塊比較多,這里筆者就說幾個筆者比較常用的板塊,分別是線程板塊和文件描述符板塊,通過這兩個板塊筆者可以日常巡檢了解是否發(fā)生線程死鎖或者程序中是否出現(xiàn)資源未能及時關閉的情況:

  • THREAD:它記錄當前活躍線程數(shù)、活躍的守護線程數(shù)、從JVM啟動開啟曾經(jīng)活著的最大線程數(shù)、總共啟動線程數(shù)以及發(fā)生死鎖的線程數(shù)。
  • FILE-DESCRIPTOR:這個板塊記錄JVM可以打開的最大文件描述符和當前已經(jīng)打開的文件描述符數(shù)。

3.查看和修改日志

logger指令也算是筆者比較喜歡的指令,它可以非常直觀的查看我們對于日志的配置,如下圖,以筆者當前運行的程序為例,可以看到如下幾個信息:

  • 日志級別為INFO。
  • 存儲錯誤日志的ERROR_FILE的相對路徑。
  • 存儲普通日志INFO_FILE的相對路徑。

當然我們也可以查看指定名字的日志信息,例如我們想查看com.example.arthasExample.TestController的日志信息,就可以直接鍵入logger -n com.example.arthasExample.TestController指令進行查看:

logger指令還有一個比較實用的功能,即直接修改日志級別,例如我們希望修改ROOT這個名稱的日志級別,就可以基于如下步驟完成修改:

  • 獲取classLoader的哈希碼。
  • 基于哈希碼通過logger指令修改日志級別。

我們程序中有這樣一段代碼,此時我們請求下面這個接口只會輸出info級別的日志:

 @GetMapping(value = {"/user/logger"})
    public String loggerPrint() {
        log.info("info logger");
        log.debug("debug logger");
        return "success";
    }

對應的輸出結果為:

2024-08-19 23:53:29.454  INFO  c.e.a.TestController          :138  http-nio-8080-exec-1                    info logger

接下來我們就直接通過arthas修改日志級別,首先我們需要獲取當前classloader的哈希碼:

sc -d com.example.arthasExample.TestController

然后我們直接通過這個哈希碼,執(zhí)行如下指令將日志設置為debug

logger -c 306a30c7 --name ROOT --level debug

于是debug日志就出現(xiàn)了:

2024-08-20 00:13:31.438  INFO  c.e.a.TestController          :138  http-nio-8080-exec-6                    info logger
2024-08-20 00:13:31.439  DEBUG c.e.a.TestController          :139  http-nio-8080-exec-6                    debug logger

4.查看JVM內(nèi)存信息

接下來就是memory指令,這也是筆者比較常用的指令之一,通過memory我們可以監(jiān)控到當前內(nèi)存的使用情況: 如下圖所示,鍵入memory指令后我們就可以看到這些區(qū)域的內(nèi)存已用、總大小、最大值以及使用率等信息:

對應的我們也給出上文中memory各行代表的含義:

  • heap:堆區(qū)內(nèi)存。
  • ps_eden_space:堆內(nèi)存中新生代Eden區(qū)。
  • ps_survivor_space:堆內(nèi)存中新生代survivor區(qū)。
  • ps_old_gen:堆內(nèi)存老年代區(qū)。
  • nonheap:非堆內(nèi)存,即堆內(nèi)存之外的內(nèi)存。
  • code_cache:因為Java執(zhí)行是將字節(jié)碼編譯為機器碼,而這個區(qū)域就是用于緩存這部分代碼。
  • metaspace:元空間,以jdk1.8為例該空間是用于存儲Java類和方法的元數(shù)據(jù)信息、常量池等。
  • compressed_class_space:存放類文件信息的區(qū)域。

對應的我們在這里也簡單的復習一下JVM內(nèi)存區(qū)域的分布,建議讀者可參考下圖了解memory指令中各個字段的含義:

5.查看JVM的環(huán)境變量

arthas的sysenv指令常用于獲取系統(tǒng)環(huán)境變量信息,鍵入這條指令我們可以看到當前java程序所使用的系統(tǒng)大部分環(huán)境變量信息,如下圖,可以看到大部分的當前系統(tǒng)用戶名稱、編碼格式、當前程序路徑以及客戶端ip和端口號等信息:

根據(jù)help的提示,這條指令同樣也支持查詢單個環(huán)境變量,不過意義不大,畢竟不是每個都知道環(huán)境變量叫什么,只有查看了才知道(笑):

[arthas@23543]$ sysenv PWD
 KEY                                              VALUE                                                                                                                                                                                               
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 PWD                                              /home/sharkchili/arthasExample

6.查看和修改JVM系統(tǒng)屬性

sysprop查看的jvm的系統(tǒng)屬性,基本上通過這個指令我們可以看到大部分的JVM參數(shù)配置信息,如下輸出結果,我們大體可以看到JDK版本、程序名稱以及日志編碼格式和當前系統(tǒng)用戶名稱等:

7.查看當前JVM線程堆棧信息

arthas提供thread指令用于查看線程情況,如下所示,它基本打印了線程計數(shù)信息和幾個活躍的線程的實時情況,默認情況下,它是按照CPU增量時間降序進行排序:

按照help的提示,我們也可以通過-n打印前幾個忙碌的線程調(diào)用堆棧信息,如下所示,筆者希望打印出前2條忙碌的線程,鍵入的指令為thread -n 2:

同時arthas也支持按照時間間隔進行輸出打印,比如我們希望列出5s內(nèi)最忙的3個線程,那么對應的指令就是:

thread -n 3 -i 5000

當我們的Java程序有大量的線程時候,我們希望篩選中某種狀態(tài)的線程,我們可以通過--state指定,例如我們希望打印處于RUNNABLE狀態(tài)的線程,那么我們就可以鍵入thread --state RUNNABLE來獲得輸出結果:

對于死鎖問題,我們也可以通過-b指令來定位查看當前程序是否存在阻塞其他線程的線程,如下圖所示,以筆者為例當前程序就不存在死鎖的情況:

此時我們給出一個觸發(fā)死鎖的接口并調(diào)用:

@RequestMapping("dead-lock")
    public void deadLock() {
        //線程1先取得鎖1,休眠后取鎖2
        new Thread(() -> {
            synchronized (lock1) {
                try {
                    log.info("t1 successfully acquired the lock1......");
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


                synchronized (lock2) {
                    log.info("t1 successfully acquired the lock1......");
                }
            }
        }, "t1").start();

        //線程2先取得鎖2,休眠后取鎖1
        new Thread(() -> {
            synchronized (lock2) {
                try {
                    log.info("t2 successfully acquired the lock2......");
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


                synchronized (lock1) {
                    log.info("t2 successfully acquired the lock1......");
                }
            }
        }, "t2").start();
    }

此時,鍵入-b指令就可以定位阻塞其他線程的線程以及所在代碼段:

8.vmtool對于JVM的調(diào)控

vmtool算是筆者用的比較多的一個工具指令,可用于查詢對象或者強制GC等功能,這些功能讀者可自行參考官網(wǎng)查閱:

vmtool:https://arthas.aliyun.com/doc/vmtool.html

而筆者這里想要介紹的是一個強制打斷線程的功能,這個指令對于特定場景下應急處理還是蠻實用的。

我們的程序調(diào)用下面的接口被系統(tǒng)監(jiān)控到CPU100%,此時我們就可以通過arthas進行特定場景下的應急處理:

@RequestMapping("cpu-100")
    public static void cpu() {
        //無限循環(huán)輸出打印
        new Thread(() -> {
            while (true) {
                log.info("cpu working");
            }
        }, "thread-1").start();
    }

我們通過thread指令看到thread-1基本將單個CPU跑滿了,并且我們通過控制臺定位到對應的id為48:

此時我們可以通過vmtool的action指令將線程打斷:

vmtool --action interruptThread -t 48

完成操作之后即可看到這個線程被我們成功打斷了:

同時vmTool也支持觀測變量的詳情,以下面這個實例變量dateTimeStr 為例,每次接口請求都會實時刷新:

private String dateTimeStr = DateUtil.formatDateTime(new Date());

    @RequestMapping(value = "/getVal")
    public String getVal() {
        dateTimeStr = DateUtil.formatDateTime(new Date());
        log.info("dateTimeStr: {}", dateTimeStr);
        return "success";
    }

如果我們希望查看此刻dateTimeStr 的值,我們就可以通過vmtool的action指定為getInstances ,然后指定類的全路徑(以筆者這段代碼為例則是com.example.arthasExample.TestController),最后鍵入表達式instances[0].dateTimeStr意為獲取當前實例的dateTimeStr:

vmtool  --action getInstances --className com.example.arthasExample.TestController  --express 'instances[0].dateTimeStr' 

此時我們就可以非常直觀的監(jiān)控到這個變量的信息了:

常見面試題:arthas統(tǒng)計方法耗時的原理是什么

watch指令示例如下:

watch com.example.MyService sayHello "{params, result, throwExp} -> { return 'Exception: ' + throwExp; }" -E

我們從指令即可看出他可以獲取到類的全路徑,對此我們不拿猜測它就是基于這個類的全路徑進行一個字節(jié)碼樁技術對類進行增強,插入一段代碼進行在方法執(zhí)行前后插入時間,實現(xiàn)耗時統(tǒng)計。

責任編輯:趙寧寧 來源: 寫代碼的SharkChili
相關推薦

2024-11-12 15:46:37

2010-05-26 10:42:20

SVN1.5配置

2018-10-15 14:26:23

運維IT技術架構

2015-06-24 10:42:19

云計算運維自動化運維ANSIBLE

2019-03-15 10:13:10

運維云計算運營

2013-12-03 13:05:30

Lua腳本語言

2009-05-19 10:19:49

網(wǎng)絡拓撲運維管理摩卡

2023-10-20 14:08:35

digDNS

2015-08-12 17:06:28

2013-03-29 09:15:08

IT運維運維人員運維工程師

2019-02-15 08:51:22

2014-06-20 10:51:35

Linux LVM邏輯卷

2021-12-01 09:53:46

CSS 技巧代碼重構

2015-07-13 10:06:11

超融合基礎架構運維數(shù)據(jù)中心

2024-07-25 11:22:23

2016-01-29 15:15:17

運維性能優(yōu)化模式

2012-06-25 16:40:54

2017-12-15 09:20:20

IT運維順豐

2016-12-13 13:15:49

運維

2019-03-19 08:41:38

Linux運維變更
點贊
收藏

51CTO技術棧公眾號