arthas的簡單用法


  有時候在生產或者測試環境有些方法執行比較耗時,一種簡單粗暴的方法是在可能的地點打日志進行監視,另一種就是借助於插件進行檢測。最近也是有機會了解並實際運用了arthas這個插件,還是挺方便的。而且也可以用於查看JVM信息、線程信息以及系統屬性等信息。

 

arthas(中文阿爾薩斯): https://arthas.aliyun.com/zh-cn/

下載:

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

0.本地准備一個java進程

package arthas;

public class ArthasTest {

    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());
        String test = System.getProperty("test");

        while (true) {
            String test2 = System.getProperty("test");
            if (test2 != null && !test2.equals(test)) {
                System.out.println(test2);
                test = test2;
            }
        }
    }
}

啟動該主類

1.啟動arthas

C:\Users\qlq\Desktop\plaintools>java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.4.5
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 20384 org.jetbrains.idea.maven.server.RemoteMavenServer36
  [2]: 1556
  [3]: 28868 arthas.ArthasTest
  [4]: 16780 org.jetbrains.jps.cmdline.Launcher
  [5]: 7676 org.jetbrains.jps.cmdline.Launcher
3
[INFO] local lastest version: 3.4.5, remote lastest version: 3.4.6, try to download from remote.
[INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/3.4.6?mirror=aliyun
[INFO] File size: 11.99 MB, downloaded size: 813.01 KB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 1.58 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 2.36 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 3.14 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 3.93 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 4.71 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 5.49 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 6.28 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 7.06 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 7.33 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 8.81 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 9.59 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 10.37 MB, downloading ...
[INFO] File size: 11.99 MB, downloaded size: 11.56 MB, downloading ...
[INFO] Download arthas success.
[INFO] arthas home: C:\Users\jxrt\.arthas\lib\3.4.6\arthas
[INFO] Try to attach process 28868
[INFO] Found java home from System Env JAVA_HOME: E:\java\JAVA8
[INFO] Attach process 28868 success.
[INFO] arthas-client connect 127.0.0.1 3658
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'


wiki      https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version   3.4.6
pid       28868
time      2021-01-12 20:54:40

[arthas@28868]$

arthas 會自動檢測進程ID,需要自己選擇一個PID然后進入,上面我輸入3

2.基本命令

1.dashboard    當前系統的實時數據面板:包括線程、JVM、操作系統屬性等

[arthas@28868]$ dashboard
ID     NAME                                       GROUP                 PRIORITY      STATE         %CPU           DELTA_TIME    TIME          INTERRUPTED    DAEMON
1      main                                       main                  5             RUNNABLE      0.0            0.000         6:9.250       false          false
-1     C1 CompilerThread3                         -                     -1            -             0.0            0.000         0:0.546       false          true
-1     C2 CompilerThread2                         -                     -1            -             0.0            0.000         0:0.296       false          true
-1     C2 CompilerThread0                         -                     -1            -             0.0            0.000         0:0.281       false          true
-1     C2 CompilerThread1                         -                     -1            -             0.0            0.000         0:0.203       false          true
25     arthas-NettyHttpTelnetBootstrap-3-2        system                5             RUNNABLE      0.0            0.000         0:0.078       false          true
5      Attach Listener                            system                5             RUNNABLE      0.0            0.000         0:0.046       false          true
-1     VM Thread                                  -                     -1            -             0.0            0.000         0:0.031       false          true
2      Reference Handler                          system                10            WAITING       0.0            0.000         0:0.015       false          true
3      Finalizer                                  system                8             WAITING       0.0            0.000         0:0.015       false          true
18     arthas-NettyHttpTelnetBootstrap-3-1        system                5             RUNNABLE      0.0            0.000         0:0.015       false          true
26     arthas-command-execute                     system                5             TIMED_WAITING 0.0            0.000         0:0.015       false          true
4      Signal Dispatcher                          system                9             RUNNABLE      0.0            0.000         0:0.000       false          true
15     arthas-timer                               system                5             WAITING       0.0            0.000         0:0.000       false          true
19     arthas-NettyWebsocketTtyBootstrap-4-1      system                5             RUNNABLE      0.0            0.000         0:0.000       false          true
20     arthas-NettyWebsocketTtyBootstrap-4-2      system                5             RUNNABLE      0.0            0.000         0:0.000       false          true
21     arthas-shell-server                        system                5             TIMED_WAITING 0.0            0.000         0:0.000       false          true
22     arthas-session-manager                     system                5             TIMED_WAITING 0.0            0.000         0:0.000       false          true
23     arthas-UserStat                            system                5             WAITING       0.0            0.000         0:0.000       false          true
27     Timer-for-arthas-dashboard-2d53a13f-e23f-4 system                5             RUNNABLE      0.0            0.000         0:0.000       false          true
-1     GC task thread#7 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#6 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     VM Periodic Task Thread                    -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#0 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     Service Thread                             -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#1 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#2 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
Memory                               used        total       max          usage       GC
heap                                 58M         241M        3582M        1.64%       gc.ps_scavenge.count                       1
ps_eden_space                        50M         63M         1322M        3.80%       gc.ps_scavenge.time(ms)                    7
ps_survivor_space                    8M          10M         10M          79.64%      gc.ps_marksweep.count                      0
ps_old_gen                           88K         172032K     2751488K     0.00%       gc.ps_marksweep.time(ms)                   0
nonheap                              27M         28M         -1           96.88%
code_cache                           5M          5M          240M         2.21%
metaspace                            19M         20M         -1           96.71%
compressed_class_space               2M          2M          1024M        0.23%
direct                               0K          0K          -            105.88%
mapped                               0K          0K          -            0.00%
Runtime
os.name                                                                               Windows 10
os.version                                                                            10.0
java.version                                                                          1.8.0_171
java.home                                                                             E:\java\JAVA8_171\jre
systemload.average                                                                    -1.00
processors                                                                            8
timestamp/uptime                                                                      Tue Jan 12 20:56:26 CST 2021/370s

  上面信息可以看到JVM的內存信息,也可以查看到每個區域的GC信息。同時也可以看到使用的垃圾收集器是JDK8默認的-XX:+UseParallelGC 使用ParallelScavenge + Serial Old(PS MarkSweep)收集器組合

2.thread    查看線程信息

[arthas@28868]$ thread
Threads Total: 29, NEW: 0, RUNNABLE: 8, BLOCKED: 0, WAITING: 4, TIMED_WAITING: 2, TERMINATED: 0, Internal threads: 15
ID     NAME                                       GROUP                 PRIORITY      STATE         %CPU           DELTA_TIME    TIME          INTERRUPTED    DAEMON
1      main                                       main                  5             RUNNABLE      101.42         0.203         8:3.609       false          false
2      Reference Handler                          system                10            WAITING       0.0            0.000         0:0.015       false          true
3      Finalizer                                  system                8             WAITING       0.0            0.000         0:0.015       false          true
4      Signal Dispatcher                          system                9             RUNNABLE      0.0            0.000         0:0.000       false          true
5      Attach Listener                            system                5             RUNNABLE      0.0            0.000         0:0.046       false          true
15     arthas-timer                               system                5             WAITING       0.0            0.000         0:0.000       false          true
18     arthas-NettyHttpTelnetBootstrap-3-1        system                5             RUNNABLE      0.0            0.000         0:0.015       false          true
19     arthas-NettyWebsocketTtyBootstrap-4-1      system                5             RUNNABLE      0.0            0.000         0:0.000       false          true
20     arthas-NettyWebsocketTtyBootstrap-4-2      system                5             RUNNABLE      0.0            0.000         0:0.000       false          true
21     arthas-shell-server                        system                5             TIMED_WAITING 0.0            0.000         0:0.000       false          true
22     arthas-session-manager                     system                5             TIMED_WAITING 0.0            0.000         0:0.000       false          true
23     arthas-UserStat                            system                5             WAITING       0.0            0.000         0:0.000       false          true
25     arthas-NettyHttpTelnetBootstrap-3-2        system                5             RUNNABLE      0.0            0.000         0:0.125       false          true
26     arthas-command-execute                     system                5             RUNNABLE      0.0            0.000         0:0.015       false          true
-1     C2 CompilerThread2                         -                     -1            -             0.0            0.000         0:0.328       false          true
-1     GC task thread#7 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#6 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     VM Periodic Task Thread                    -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#0 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     C2 CompilerThread0                         -                     -1            -             0.0            0.000         0:0.296       false          true
-1     Service Thread                             -                     -1            -             0.0            0.000         0:0.000       false          true
-1     C2 CompilerThread1                         -                     -1            -             0.0            0.000         0:0.218       false          true
-1     GC task thread#1 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     C1 CompilerThread3                         -                     -1            -             0.0            0.000         0:0.609       false          true
-1     VM Thread                                  -                     -1            -             0.0            0.000         0:0.031       false          true
-1     GC task thread#2 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#3 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#5 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#4 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true

例如:thread 1會打印線程ID 1的棧,通常是main函數的線程。

[arthas@28868]$ thread 1 | grep 'main('
    at arthas.ArthasTest.main(ArthasTest.java:15)

補充:也可以查看線程的阻塞情況,只支持找出synchronized關鍵字阻塞住的線程, 如果是java.util.concurrent.Lock, 目前還不支持。

如下一段程序:

package arthas;

public class ArthasTest {

    public static void main(String[] args) {
        MyTask myTask = new MyTask();
        for (int i = 0; i < 2; i++) {
            new Thread(myTask).start();
        }
    }
}

class MyTask implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "開始執行");
        synchronized (this) {
            System.out.println(Thread.currentThread().getName() + " 占用鎖");
            try {
                Thread.sleep(1 * 30 * 60 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

結果:

Thread-0開始執行
Thread-0 占用鎖
Thread-1開始執行

可以用jstack查看,也可以用arthas:如下

[arthas@22336]$ thread -b
"Thread-0" Id=14 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at arthas.MyTask.run(ArthasTest.java:21)
    -  locked arthas.MyTask@7253ba6b <---- but blocks 1 other threads!
    at java.lang.Thread.run(Thread.java:748)

[arthas@22336]$ thread
Threads Total: 31, NEW: 0, RUNNABLE: 8, BLOCKED: 1, WAITING: 4, TIMED_WAITING: 3, TERMINATED: 0, Internal threads: 15
ID     NAME                                       GROUP                 PRIORITY      STATE         %CPU           DELTA_TIME    TIME          INTERRUPTED    DAEMON
2      Reference Handler                          system                10            WAITING       0.0            0.000         0:0.000       false          true
3      Finalizer                                  system                8             WAITING       0.0            0.000         0:0.000       false          true
4      Signal Dispatcher                          system                9             RUNNABLE      0.0            0.000         0:0.000       false          true
5      Attach Listener                            system                5             RUNNABLE      0.0            0.000         0:0.031       false          true
18     arthas-timer                               system                5             WAITING       0.0            0.000         0:0.000       false          true
21     arthas-NettyHttpTelnetBootstrap-3-1        system                5             RUNNABLE      0.0            0.000         0:0.031       false          true
22     arthas-NettyWebsocketTtyBootstrap-4-1      system                5             RUNNABLE      0.0            0.000         0:0.000       false          true
23     arthas-NettyWebsocketTtyBootstrap-4-2      system                5             RUNNABLE      0.0            0.000         0:0.000       false          true
24     arthas-shell-server                        system                5             TIMED_WAITING 0.0            0.000         0:0.000       false          true
25     arthas-session-manager                     system                5             TIMED_WAITING 0.0            0.000         0:0.000       false          true
26     arthas-UserStat                            system                5             WAITING       0.0            0.000         0:0.000       false          true
28     arthas-NettyHttpTelnetBootstrap-3-2        system                5             RUNNABLE      0.0            0.000         0:0.093       false          true
29     arthas-command-execute                     system                5             RUNNABLE      0.0            0.000         0:0.015       false          true
14     Thread-0                                   main                  5             TIMED_WAITING 0.0            0.000         0:0.000       false          false
15     Thread-1                                   main                  5             BLOCKED       0.0            0.000         0:0.000       false          false
16     DestroyJavaVM                              main                  5             RUNNABLE      0.0            0.000         0:0.343       false          false
-1     C2 CompilerThread2                         -                     -1            -             0.0            0.000         0:0.218       false          true
-1     GC task thread#7 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#6 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     VM Periodic Task Thread                    -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#0 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     C2 CompilerThread0                         -                     -1            -             0.0            0.000         0:0.203       false          true
-1     Service Thread                             -                     -1            -             0.0            0.000         0:0.000       false          true
-1     C2 CompilerThread1                         -                     -1            -             0.0            0.000         0:0.218       false          true
-1     GC task thread#1 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     C1 CompilerThread3                         -                     -1            -             0.0            0.000         0:0.640       false          true
-1     VM Thread                                  -                     -1            -             0.0            0.000         0:0.015       false          true
-1     GC task thread#2 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#3 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#5 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true
-1     GC task thread#4 (ParallelGC)              -                     -1            -             0.0            0.000         0:0.000       false          true

[arthas@22336]$ thread 15
"Thread-1" Id=15 BLOCKED on arthas.MyTask@7253ba6b owned by "Thread-0" Id=14
    at arthas.MyTask.run(ArthasTest.java:19)
    -  blocked on arthas.MyTask@7253ba6b
    at java.lang.Thread.run(Thread.java:748)

thread -b  找出當前阻塞其他線程的線程。 可以看到 Thread-0 阻塞了其他一個線程

Thread 查看線程狀態可以看到ID為15的Thread-1處於阻塞狀態。

Thread 15 查看具體的信息,可以看到當前阻塞的資源被哪個線程占有等情況。

 

3. jad   反編譯類信息

[arthas@28868]$ jad arthas.ArthasTest

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@18b4aac2
  +-sun.misc.Launcher$ExtClassLoader@3af87f7

Location:
/E:/xiangmu/MvnPro/target/classes/

/*
 * Decompiled with CFR.
 */
package arthas;

public class ArthasTest {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());
        String test = System.getProperty("test");
        while (true) {
            String test2;
            if ((test2 = System.getProperty("test")) == null || test2.equals(test)) {
                continue;
            }
            System.out.println(test2);
            test = test2;
        }
    }
}

4. 開啟保存日志

options 查看配置,相當於查看arthas內置的全局配置屬性

options save-result true 開啟保存日志。會保存到{user}/logs\arthas-cache/result.log 中

5.退出

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

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

3. 實操

1. 修改以及查看JVM的環境變量和JVM的系統屬性

sysenv 查看JVM的環境變量
sysprop 查看JVM的所有的系統屬性
sysprop java.version 查看單個系統的屬性
sysprop user.country US 修改user.country 屬性的值為US

比如上面修改 test 屬性為 testValue,修改之后會被程序System.getProperty(key) 獲取到

[arthas@28868]$ sysprop  test testValue
Successfully changed the system property.
 KEY                               VALUE
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 test                              testValue
[arthas@28868]$ sysprop  test
 KEY                               VALUE
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 test                              testValue

我們到IDEA查看main線程打出的信息:testValue

2. 監視方法的執行時長以及方法的返回值

比如如下簡單的Controller和Service:

controller:

package com.xm.ggn.controller;

import com.xm.ggn.service.common.MessageService2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @Value("${test:defaultValue}")
    private String test;

    @RequestMapping("test")
    public String test() {
        return test;
    }

    @Autowired
    private MessageService2 messageService;

    @RequestMapping("tx1")
    public void tx1() {
        messageService.tx1();
    }

    @RequestMapping("tx2")
    public void tx2() {
        messageService.tx2();
    }

    @RequestMapping("tx4")
    public void tx4() {
        messageService.tx4();
    }

}

service:

package com.xm.ggn.service.common;

public interface MessageService2 {

    void tx1();

    void tx2();

    void tx3();

    void tx4();
}

serviceimpl:

package com.xm.ggn.service.common.impl;

import com.xm.ggn.bean.common.Message;
import com.xm.ggn.mapper.common.MessageMapper;
import com.xm.ggn.service.common.MessageService2;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;

@Service
//@Transactional
public class MessageService2Impl implements MessageService2 {

    @Autowired
    private MessageMapper messageMapper;

    @Override
    @Transactional
    public void tx1() {
        // 調用tx3方法會回滾,因為這里有事務直接,會走代理,且tx3方法會加入本事務
        tx3();
    }

    @Override
    public void tx2() {
        try {
            Thread.sleep(1 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 調用tx3方法不會回滾,因為這里沒有事務。即使tx3有事務也不會走代理,因為通過內部方法調用不會走代理。解決辦法查看tx4 方法
        tx3();
    }

    @Override
    @Transactional
    public void tx3() {
        Message message = new Message();
        message.setTitle("tx3");
        messageMapper.insert(message);

        int i = 1 / 0;
    }

    //  這樣進行方法內部調用AOP會生效,主啟動類加@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true) 注解
    @Override
    public void tx4() {
        MessageService2 messageService = (MessageService2) AopContext.currentProxy();
        // 這樣調用tx3會進行回滾,走的是代理類的方法
        messageService.tx3();
    }
}

啟動應用后啟動arthas並且監視對應進程

1. 搜索類以及反編譯查看AOP增強的類

1. 搜索:模糊搜索

[arthas@13232]$ sc *.MessageService2
com.xm.ggn.service.common.MessageService2
com.xm.ggn.service.common.impl.MessageService2Impl
com.xm.ggn.service.common.impl.MessageService2Impl$$EnhancerBySpringCGLIB$$7fa3a2fc
Affect(row-cnt:3) cost in 56 ms.

如果查看加載的所有類,可以用:

sc *

2. 反編譯查看AOP增強的類

[arthas@13232]$ jad com.xm.ggn.service.common.impl.MessageService2Impl$$EnhancerBySpringCGLIB$$7fa3a2fc

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@18b4aac2
  +-sun.misc.Launcher$ExtClassLoader@3c22fc4c

Location:
/E:/xiangmu/bs-media/media-server/target/classes/

/*
 * Decompiled with CFR.
 *
 * Could not load the following classes:
 *  com.xm.ggn.service.common.impl.MessageService2Impl
 */
package com.xm.ggn.service.common.impl;

import com.xm.ggn.service.common.impl.MessageService2Impl;
import java.lang.reflect.Method;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Dispatcher;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;

public class MessageService2Impl$$EnhancerBySpringCGLIB$$7fa3a2fc
extends MessageService2Impl
implements SpringProxy,
Advised,
Factory {
    private boolean CGLIB$BOUND;
    public static Object CGLIB$FACTORY_DATA;
    ...
}

2. 檢測方法的執行時長: trace

比如檢測:com.xm.ggn.controller.TestController 類的所有方法,如下:

[arthas@13232]$ trace com.xm.ggn.controller.TestController *
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 5) cost in 93 ms, listenerId: 1
`---ts=2021-01-12 21:15:57;thread_name=http-nio-8088-exec-1;id=108;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@3ee39a1c
    `---[45.0785ms] com.xm.ggn.controller.TestController:tx4() [throws Exception]
        +---[44.0299ms] com.xm.ggn.service.common.MessageService2:tx4() #40 [throws Exception]
        `---throw:java.lang.ArithmeticException #39 [/ by zero]

  trace還有好幾個參數可以過濾以及支持檢測多個類的多個方法以及根據時長過濾等

補充:用trace命令檢測多個類的多個方法,形成調用鏈檢測

比如如下

(1) Service1

package com.xm.ggn.test.arthas;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author: 喬利強
 * @date: 2021/2/7 14:37
 * @description:
 */
@Service
@Slf4j
public class ArthasTestService {

    @Autowired
    private ArthasTestService2 arthasTestService2;

    public void method1() {
        log.debug("method1");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException ignore) {
        }

        this.method2();
        this.method3();
    }


    public void method2() {
        log.debug("method2");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException ignore) {
        }

        arthasTestService2.method1();
        arthasTestService2.method2();
    }

    public void method3() {
        log.debug("method3");
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException ignore) {
        }
    }

}

(2)Service2

package com.xm.ggn.test.arthas;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author: 喬利強
 * @date: 2021/2/7 14:37
 * @description:
 */
@Service
@Slf4j
public class ArthasTestService2 {

    public void method1() {
        log.debug("method1");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException ignore) {
        }
    }

    public void method2() {
        log.debug("method2");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException ignore) {
        }
    }
} 

(3)Controller

package com.xm.ggn.test.arthas;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: 喬利強
 * @date: 2021/2/7 14:34
 * @description:
 */
@RestController
@RequestMapping("/arthas")
public class ArthasTestCcontroller {

    @Autowired
    private ArthasTestService arthasTestService;

    @GetMapping("testTrace")
    public void testTrace() {
        arthasTestService.method1();
    }
}

(4)測試:

1》trace檢測單個類,結果如下: 可以看到沒監測ArthasTestService2 內部調用時長

[arthas@28892]$ sc *.ArthasTestService*
com.xm.ggn.test.arthas.ArthasTestService
com.xm.ggn.test.arthas.ArthasTestService2
Affect(row-cnt:2) cost in 50 ms.
[arthas@28892]$ trace com.xm.ggn.test.arthas.ArthasTestService *
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 4) cost in 83 ms, listenerId: 1
`---ts=2021-02-07 19:32:08;thread_name=http-nio-8088-exec-1;id=12e;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@87060c0
    `---[9003.109599ms] com.xm.ggn.test.arthas.ArthasTestService:method1()
        +---[0.035ms] org.slf4j.Logger:debug() #22
        +---[5002.6882ms] com.xm.ggn.test.arthas.ArthasTestService:method2() #28
        |   `---[5002.1293ms] com.xm.ggn.test.arthas.ArthasTestService:method2()
        |       +---[0.008ms] org.slf4j.Logger:debug() #34
        |       +---[1000.8634ms] com.xm.ggn.test.arthas.ArthasTestService2:method1() #40
        |       `---[2000.6096ms] com.xm.ggn.test.arthas.ArthasTestService2:method2() #41
        `---[3000.115601ms] com.xm.ggn.test.arthas.ArthasTestService:method3() #29
            `---[3000.07ms] com.xm.ggn.test.arthas.ArthasTestService:method3()
                `---[0.007ms] org.slf4j.Logger:debug() #45

2》 監測兩個類的多個方法: 可以看到也監測了ArthasTestService2的相關方法

[arthas@28892]$ trace -E com.xm.ggn.test.arthas.ArthasTestService|com.xm.ggn.test.arthas.ArthasTestService2 method1|method2|method3
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 5) cost in 122 ms, listenerId: 3
`---ts=2021-02-07 19:34:51;thread_name=http-nio-8088-exec-4;id=131;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@87060c0
    `---[9002.5463ms] com.xm.ggn.test.arthas.ArthasTestService:method1()
        +---[0.0627ms] org.slf4j.Logger:debug() #22
        +---[5001.5262ms] com.xm.ggn.test.arthas.ArthasTestService:method2() #28
        |   `---[5001.484ms] com.xm.ggn.test.arthas.ArthasTestService:method2()
        |       +---[0.008101ms] org.slf4j.Logger:debug() #34
        |       +---[1000.377399ms] com.xm.ggn.test.arthas.ArthasTestService2:method1() #40
        |       |   `---[1000.288999ms] com.xm.ggn.test.arthas.ArthasTestService2:method1()
        |       |       `---[0.0178ms] org.slf4j.Logger:debug() #18
        |       `---[2000.178ms] com.xm.ggn.test.arthas.ArthasTestService2:method2() #41
        |           `---[2000.134ms] com.xm.ggn.test.arthas.ArthasTestService2:method2()
        |               `---[0.0112ms] org.slf4j.Logger:debug() #26
        `---[3000.27ms] com.xm.ggn.test.arthas.ArthasTestService:method3() #29
            `---[3000.235499ms] com.xm.ggn.test.arthas.ArthasTestService:method3()
                `---[0.007101ms] org.slf4j.Logger:debug() #45

  這里暫時沒找到監測兩個類或多個類所有方法的套路~~~

結果解釋:

(1)[5001.5262ms] com.xm.ggn.test.arthas.ArthasTestService:method2() #28  當前節點在當前步驟的耗時,單位為毫秒。 #28 表示在源文件的第28行。

(2)還有另一種寫法:[min=0.020435ms,max=0.022325ms,total=0.04276ms,count=2] org.springframework.util.Assert:isTrue() #95 表示對該方法中相同的方法調用進行了合並。比如:

if ("1".equals(a) && "2".equals(b)) {

  // doXXX

} 

3.查看某個類調用過程中的返回值: 比如觀察方法出參和返回值  watch

[arthas@19792]$ watch com.xm.ggn.controller.TestController * "{params,returnObj}"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 5) cost in 79 ms, listenerId: 3
method=com.xm.ggn.controller.TestController.test location=AtExit
ts=2021-01-12 21:32:16; [cost=0.0674ms] result=@ArrayList[
    @Object[][isEmpty=true;size=0],
    @String[defaultValue],
]

調用一次test 方法之后結果如上。可以看到參數為空,返回值是一個String值為"defaultValue"。

這個結果可能不太明顯,增加一個測試用例:

(1)Controller增加一個方法:

    @RequestMapping("testMap")
    public Map test(String key1, String key2) {
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        stringObjectHashMap.put(key1, key1);
        stringObjectHashMap.put(key2, key2);
        return stringObjectHashMap;
    }

(2)arthas檢測: -x 指定輸出結果的屬性遍歷深度,默認為 1

[arthas@27848]$ watch com.xm.ggn.controller.TestController * "{params,returnObj}" -x 3
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 6) cost in 38 ms, listenerId: 5

(3)訪問:

http://localhost:8088/testMap?key1=111&key2=222

(4)arthas控制台輸出

method=com.xm.ggn.controller.TestController.test location=AtExit
ts=2021-01-12 21:40:26; [cost=0.0351ms] result=@ArrayList[
    @Object[][
        @String[111],
        @String[222],
    ],
    @HashMap[
        @String[111]:@String[111],
        @String[222]:@String[222],
    ],
]

補充:第一次運行jar包選擇進程進入的時候會自動從互聯網下載幾個依賴包,自動放在 ${user}/.arthas/lib。如果是離線環境可以將lib下面的包傳到離線的服務器,啟動的時候指定路徑:如下:

java -jar arthas-boot.jar --arthas-home C:\Users\qlq\Desktop\plaintools\arthas\lib\3.4.5\arthas

--arthas-home 指定依賴包的路徑

補充:Arthas目前支持Web Console,用戶在attach成功之后,可以直接訪問:http://127.0.0.1:3658/。默認情況下,arthas只listen 127.0.0.1,所以如果想從遠程連接,則可以使用 --target-ip參數指定listen的IP,更多參考-h的幫助說明。

補充:logger查看以及修改日志級別 

[arthas@11520]$ logger  #查看日志級別
 name                ROOT
 class               ch.qos.logback.classic.Logger
 classLoader         sun.misc.Launcher$AppClassLoader@18b4aac2
 classLoaderHash     18b4aac2
 level               INFO
 effectiveLevel      INFO
 additivity          true
 codeSource          file:/E:/Maven/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar
 appenders           name            CONSOLE
                     class           ch.qos.logback.core.ConsoleAppender
                     classLoader     sun.misc.Launcher$AppClassLoader@18b4aac2
                     classLoaderHash 18b4aac2
                     target          System.out

[arthas@11520]$ logger --name ROOT --level debug  #修改日志級別
Update logger level success.
[arthas@11520]$ logger  #查看日志級別
 name                ROOT
 class               ch.qos.logback.classic.Logger
 classLoader         sun.misc.Launcher$AppClassLoader@18b4aac2
 classLoaderHash     18b4aac2
 level               DEBUG
 effectiveLevel      DEBUG
 additivity          true
 codeSource          file:/E:/Maven/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar
 appenders           name            CONSOLE
                     class           ch.qos.logback.core.ConsoleAppender
                     classLoader     sun.misc.Launcher$AppClassLoader@18b4aac2
                     classLoaderHash 18b4aac2
                     target          System.out

補充:sc 也可以查看類以及靜態變量的信息,如下:

[arthas@9432]$  sc -d -f com.xm.ggn.test.FieldTest
 class-info        com.xm.ggn.test.FieldTest
 code-source       /E:/xiangmu/bs-media/media-server/target/classes/
 name              com.xm.ggn.test.FieldTest
 isInterface       false
 isAnnotation      false
 isEnum            false
 isAnonymousClass  false
 isArray           false
 isLocalClass      false
 isMemberClass     false
 isPrimitive       false
 isSynthetic       false
 simple-name       FieldTest
 modifier          public
 annotation
 interfaces
 super-class       +-java.lang.Object
 class-loader      +-sun.misc.Launcher$AppClassLoader@18b4aac2
                     +-sun.misc.Launcher$ExtClassLoader@707ed9b0
 classLoaderHash   18b4aac2
 fields            name     test
                   type     java.lang.String
                   modifier final,public,static
                   value    123

                   name     name
                   type     java.lang.String
                   modifier private

也可以使用ognl獲取靜態變量:

[arthas@9432]$ ognl '@com.xm.ggn.test.FieldTest@test'
@String[123]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM