成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

簡(jiǎn)明的 Arthas 配置及基礎(chǔ)運(yùn)維教程

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

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

一、簡(jiǎn)述Arthas的運(yùn)行原理(理解)

arthas的運(yùn)行原理大致是以下幾個(gè)步驟:

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

二、詳解Arthas基礎(chǔ)使用

1.下載安裝

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

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

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

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

完成后我們通過(guò)下面這個(gè)命令就可以將Arthas啟動(dòng)了。

java -jar arthas-boot.jar

此時(shí)我們就可以看到對(duì)應(yīng)的進(jìn)程序號(hào)和進(jìn)程的pid,以筆者為例,開(kāi)啟arthas之后就會(huì)看到一個(gè)序號(hào)為1的9121的Java進(jìn)程,我們可以直接點(diǎn)擊1并輸入回車對(duì)此進(jìn)程進(jìn)行監(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初次會(huì)進(jìn)行相關(guān)依賴下載,然后我們就可以正式的使用arthas管理當(dāng)前進(jìn)程了:

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

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

完成后下載并解壓之后,我們可以直接通過(guò)下面這個(gè)腳本指令快速啟動(dòng)arthas:

./as.sh

3.常見(jiàn)指令介紹

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

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

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

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

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

memory |grep ps_old_gen

點(diǎn)擊quit會(huì)直接退出當(dāng)前進(jìn)程的客戶端,stop同理只不過(guò)多是連著服務(wù)端和其他客戶端一并殺掉,這里就不多做演示了:

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

4.快捷啟動(dòng)配置

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

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

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

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

然后通過(guò)source指令使其生效:

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

# 鍵入as
sharkchili@DESKTOP-xxx:~$ as
# 直接快速啟動(dòng)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中比較常用的運(yùn)維指令

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

日常開(kāi)發(fā)維護(hù)過(guò)程中對(duì)于項(xiàng)目的巡檢還是蠻重要的,通過(guò)Arthas的dashboard可以非常直觀的查看當(dāng)前系統(tǒng)中進(jìn)程的運(yùn)行情況。

在arthas的控制面板輸入dashboard,默認(rèn)情況下5s進(jìn)行一次刷新:

這里我們來(lái)簡(jiǎn)單介紹一下第一板塊線程中的字段的含義:

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

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

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

所以如果我們希望每1s刷新1次,刷新5次,那么對(duì)應(yīng)的命令就是:

dashboard -i 1000 -n 5

2.查看JVM信息

arthas也可能非常直觀的查看jvm信息,對(duì)應(yīng)的指令也就是jvm。

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

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

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

3.查看和修改日志

logger指令也算是筆者比較喜歡的指令,它可以非常直觀的查看我們對(duì)于日志的配置,如下圖,以筆者當(dāng)前運(yùn)行的程序?yàn)槔梢钥吹饺缦聨讉€(gè)信息:

  • 日志級(jí)別為INFO。
  • 存儲(chǔ)錯(cuò)誤日志的ERROR_FILE的相對(duì)路徑。
  • 存儲(chǔ)普通日志INFO_FILE的相對(duì)路徑。

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

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

  • 獲取classLoader的哈希碼。
  • 基于哈希碼通過(guò)logger指令修改日志級(jí)別。

我們程序中有這樣一段代碼,此時(shí)我們請(qǐng)求下面這個(gè)接口只會(huì)輸出info級(jí)別的日志:

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

對(duì)應(yīng)的輸出結(jié)果為:

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

接下來(lái)我們就直接通過(guò)arthas修改日志級(jí)別,首先我們需要獲取當(dāng)前classloader的哈希碼:

sc -d com.example.arthasExample.TestController

然后我們直接通過(guò)這個(gè)哈希碼,執(zhí)行如下指令將日志設(shè)置為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)存信息

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

對(duì)應(yīng)的我們也給出上文中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:因?yàn)镴ava執(zhí)行是將字節(jié)碼編譯為機(jī)器碼,而這個(gè)區(qū)域就是用于緩存這部分代碼。
  • metaspace:元空間,以jdk1.8為例該空間是用于存儲(chǔ)Java類和方法的元數(shù)據(jù)信息、常量池等。
  • compressed_class_space:存放類文件信息的區(qū)域。

對(duì)應(yīng)的我們?cè)谶@里也簡(jiǎn)單的復(fù)習(xí)一下JVM內(nèi)存區(qū)域的分布,建議讀者可參考下圖了解memory指令中各個(gè)字段的含義:

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

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

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

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

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

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

7.查看當(dāng)前JVM線程堆棧信息

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

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

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

thread -n 3 -i 5000

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

對(duì)于死鎖問(wèn)題,我們也可以通過(guò)-b指令來(lái)定位查看當(dāng)前程序是否存在阻塞其他線程的線程,如下圖所示,以筆者為例當(dāng)前程序就不存在死鎖的情況:

此時(shí)我們給出一個(gè)觸發(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();
    }

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

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

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

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

而筆者這里想要介紹的是一個(gè)強(qiáng)制打斷線程的功能,這個(gè)指令對(duì)于特定場(chǎng)景下應(yīng)急處理還是蠻實(shí)用的。

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

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

我們通過(guò)thread指令看到thread-1基本將單個(gè)CPU跑滿了,并且我們通過(guò)控制臺(tái)定位到對(duì)應(yīng)的id為48:

此時(shí)我們可以通過(guò)vmtool的action指令將線程打斷:

vmtool --action interruptThread -t 48

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

同時(shí)vmTool也支持觀測(cè)變量的詳情,以下面這個(gè)實(shí)例變量dateTimeStr 為例,每次接口請(qǐng)求都會(huì)實(shí)時(shí)刷新:

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 的值,我們就可以通過(guò)vmtool的action指定為getInstances ,然后指定類的全路徑(以筆者這段代碼為例則是com.example.arthasExample.TestController),最后鍵入表達(dá)式instances[0].dateTimeStr意為獲取當(dāng)前實(shí)例的dateTimeStr:

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

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

常見(jiàn)面試題:arthas統(tǒng)計(jì)方法耗時(shí)的原理是什么

watch指令示例如下:

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

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

責(zé)任編輯:趙寧寧 來(lái)源: 寫(xiě)代碼的SharkChili
相關(guān)推薦

2025-05-08 08:20:00

Arthas開(kāi)源Java

2024-11-12 15:46:37

2010-05-26 10:42:20

SVN1.5配置

2018-10-15 14:26:23

運(yùn)維IT技術(shù)架構(gòu)

2015-06-24 10:42:19

云計(jì)算運(yùn)維自動(dòng)化運(yùn)維ANSIBLE

2019-03-15 10:13:10

運(yùn)維云計(jì)算運(yùn)營(yíng)

2013-12-03 13:05:30

Lua腳本語(yǔ)言

2009-05-19 10:19:49

網(wǎng)絡(luò)拓?fù)?/a>運(yùn)維管理摩卡

2015-08-12 17:06:28

2023-10-20 14:08:35

digDNS

2013-03-29 09:15:08

IT運(yùn)維運(yùn)維人員運(yùn)維工程師

2015-07-13 10:06:11

超融合基礎(chǔ)架構(gòu)運(yùn)維數(shù)據(jù)中心

2024-07-25 11:22:23

2012-06-25 16:40:54

2016-01-29 15:15:17

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

2017-12-15 09:20:20

IT運(yùn)維順豐

2016-12-13 13:15:49

運(yùn)維

2019-02-15 08:51:22

2014-06-20 10:51:35

Linux LVM邏輯卷

2021-12-01 09:53:46

CSS 技巧代碼重構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 9999国产精品欧美久久久久久 | 国产免费一区二区 | 一区二区三区电影在线观看 | 日本五月婷婷 | 天天精品在线 | 亚洲精品久久久久久久久久久 | 成人免费视频网站在线观看 | 黄视频免费观看 | 美国黄色一级片 | 日日爱av| 亚洲高清一区二区三区 | 日韩一二三区 | 色婷婷综合久久久中字幕精品久久 | 欧美色专区 | 一区二区三区视频在线观看 | 91超碰在线 | 日韩中文字幕 | 韩日在线视频 | 国产一区二区三区四区hd | 在线观看国产视频 | 亚洲欧洲精品一区 | 毛片免费视频 | 日韩一区二区在线视频 | 国产在线二区 | 午夜大片 | 精品视频一区二区三区四区 | 羞羞的视频在线 | 国内精品久久久久久 | 婷婷在线视频 | 理论片免费在线观看 | 色永久| 免费爱爱视频 | 91亚洲精品久久久电影 | 黄色大片免费看 | 搞av.com| 日韩视频精品 | 精品视频久久久久久 | 中文字幕在线一区二区三区 | 神马久久久久久久久久 | 91在线播| 99re视频在线 |