arthas的简单用法

技术文章 11个月前 完美者
1,517 0

标签:mis   线程id   @Value   manager   map   sso   interrupt   group   net   

  有时候在生产或者测试环境有些方法执行比较耗时,一种简单粗暴的方法是在可能的地点打日志进行监视,另一种就是借助于插件进行检测。最近也是有机会了解并实际运用了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

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)

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还有好几个参数可以过滤以及支持检测多个类的多个方法以及根据时长过滤等

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的帮助说明。

 

arthas的简单用法

标签:mis   线程id   @Value   manager   map   sso   interrupt   group   net   

原文地址:https://www.cnblogs.com/qlqwjy/p/14269457.html

版权声明:完美者 发表于 2021-01-14 10:43:06。
转载请注明:arthas的简单用法 | 完美导航

暂无评论

暂无评论...