• 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:UsersqlqDesktopplaintools>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:Usersjxrt.arthaslib3.4.6arthas
    [INFO] Try to attach process 28868
    [INFO] Found java home from System Env JAVA_HOME: E:javaJAVA8
    [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:javaJAVA8_171jre
    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}/logsarthas-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:UsersqlqDesktopplaintoolsarthaslib3.4.5arthas

    --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]
  • 相关阅读:
    Python之文件操作
    document.hasFocus() & $(window).blur()
    innerHtml 会忽略里面元素的属性
    ng  命令集合
    阿里云ECS CentOs7.3下搭建LAMP环境(Apache2.4 + Mysql5.7 + PHP5.6 + Laravel5.2)
    在忘记root密码的时候,可以这样 亲测可用
    下一次装mysql 试一下这个方法
    CentOS-6.8安装Mysql-5.5.29
    阿里云服务器下安装LAMP环境(CentOS Linux 6.3)
    CentOS 7.2 配置Apache服务(httpd)--上篇
  • 原文地址:https://www.cnblogs.com/360minitao/p/15246963.html
Copyright © 2020-2023  润新知