JVM系列(四十二) JVM调优实战-Arthas 监控相关命令 watch/trace/stack/minitor

200 阅读3分钟

Arthas 监控相关命令 watch/stack/trace/minitor/tt

前面我们学习了 sm/sc/jad/mc/redefine等命令,适用于类相关的命令,今天我们来看下其他的命令,包括 watch/stack/trace/minitor/tt 特别是stack, watch,trace这三个,是日常我们项目工作时候必须的几个功能

1.演示代码

现在我们的TestController 有一段下面的代码,我们来演示一下 watch

@GetMapping("/print")
private String getScore(Integer score) {
    log.debug("debug ===========");
    log.info("info ===========");
    log.error("error ===========");


    //输入分数超过 100, 就取100,否则返回真正的分数
    if (score > 100) {
        return "10";
    }

    return String.valueOf(score);
}

2.watch 查看方法信息

watch 命令主要用于查看线上的方法,入参,返回值等信息

  • 1、查看方法入参、返回值
  • 2、过滤无用的输出
  • 3、查看类中的成员变量
  • 4、无法查看方法中的局部变量

我们查看方法入参和返回值信息

执行 watch com.jzj.jvmtest.font.TestController getScore '{params,returnObj}' -x 3 什么意思?

  • watch 监控类 com.jzj.jvmtest.font.TestController
  • TestController 的方法getScore
  • 方法的 {params,returnObj} 参数,返回值
  • -x 3 输出对象 深度遍历3层

执行后等待,然后另开一个窗口,去访问该 TestController的 getScore方法,看是否能够监控到输入输出信息

[arthas@13016]$ watch com.jzj.jvmtest.font.TestController getScore '{params,returnObj}' -x 3
Press Q or Ctrl+C to abort.

我们执行该方法 3次, 分别是

  • curl 127.0.0.1:8078/print?score=44
  • curl 127.0.0.1:8078/print?score=55
  • curl 127.0.0.1:8078/print?score=66 执行日志如下
PS C:\Users\jzj> curl 127.0.0.1:8078/print?score=44
StatusCode        : 200
Content           : 44
                                                                                               PS C:\Users\jzj> curl 127.0.0.1:8078/print?score=55
StatusCode        : 200
Content           : 55

PS C:\Users\jzj> curl 127.0.0.1:8078/print?score=66
StatusCode        : 200
Content           : 66

watch检测的返回之信息如下

  • 第一次 输入是@Integer[44], 返回是 @String[44]
  • 第二次 输入是@Integer[55], 返回是 @String[55],
  • 第三次 输入是@Integer[66], 返回是 @String[66],
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 32 ms, listenerId: 4
method=com.jzj.jvmtest.font.TestController.getScore location=AtExit
ts=2023-05-07 12:56:03; [cost=0.3413ms] result=@ArrayList[
    @Object[][
        @Integer[44],
    ],
    @String[44],
]
method=com.jzj.jvmtest.font.TestController.getScore location=AtExit
ts=2023-05-07 12:56:05; [cost=0.2543ms] result=@ArrayList[
    @Object[][
        @Integer[55],
    ],
    @String[55],
]
method=com.jzj.jvmtest.font.TestController.getScore location=AtExit
ts=2023-05-07 12:56:07; [cost=0.2831ms] result=@ArrayList[
    @Object[][
        @Integer[66],
    ],
    @String[66],
]

image.png

我们还可以过滤 不需要的请求,输入参数是55的不监控

执行命令,过滤参数

watch com.jzj.jvmtest.font.TestController getScore '{params,returnObj}' "params[0]==55" -x 3

[arthas@13016]$ watch com.jzj.jvmtest.font.TestController getScore '{params,returnObj}' "params[0]==55" -x 3
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 33 ms, listenerId: 7
method=com.jzj.jvmtest.font.TestController.getScore location=AtExit
ts=2023-05-07 13:08:15; [cost=0.2861ms] result=@ArrayList[
    @Object[][
        @Integer[55],
    ],
    @String[55],
]
method=com.jzj.jvmtest.font.TestController.getScore location=AtExit
ts=2023-05-07 13:08:30; [cost=0.2492ms] result=@ArrayList[
    @Object[][
        @Integer[55],
    ],
    @String[55],

连续访问3次 PS C:\Users\jzj> curl 127.0.0.1:8078/print?score=“55” PS C:\Users\jzj> curl 127.0.0.1:8078/print?score=“55” PS C:\Users\jzj> curl 127.0.0.1:8078/print?score=“66”

可以看到监控结果, 只输出了 监控输入参数 55的 请求, 66的被过滤掉

image.png

3.trace 追踪方法耗时

神器,我们可以用trace 命令,查该方法的调用链路及耗时信息,trace可以统计整个调用链路上的所有性能开销和追踪调用链路。监控整个调用路径的耗时,找出真正的性能瓶颈,耗时方法,进而解决问题

还是之前的例子,我们用trace 来追踪 TestController getScore方法的耗时信息

执行 trace com.jzj.jvmtest.font.TestController getScore

[arthas@13016]$ trace com.jzj.jvmtest.font.TestController getScore
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 51 ms, listenerId: 8
`---ts=2023-05-07 13:11:54;thread_name=http-nio-8078-exec-4;id=2d;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@7e22550a
    `---[0.3982ms] com.jzj.jvmtest.font.TestController:getScore()
        +---[7.38% 0.0294ms ] org.slf4j.Logger:debug() #19
        +---[41.99% 0.1672ms ] org.slf4j.Logger:info() #20
        `---[20.77% 0.0827ms ] org.slf4j.Logger:error() #21

`---ts=2023-05-07 13:11:56;thread_name=http-nio-8078-exec-5;id=2e;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@7e22550a
    `---[0.2815ms] com.jzj.jvmtest.font.TestController:getScore()
        +---[3.37% 0.0095ms ] org.slf4j.Logger:debug() #19
        +---[52.18% 0.1469ms ] org.slf4j.Logger:info() #20
        `---[29.24% 0.0823ms ] org.slf4j.Logger:error() #21

可以看到执行结果,把所有的方法调用耗时全都打印出来了

  • 链路 7.38%的耗时 花费时间0.0294ms 19行Logger:debug() 方法
  • 链路 41.99%的耗时 花费时间0.1672ms 20行Logger:info() 方法
  • 链路 20.77%的耗时 花费时间0.0827ms 21行Logger:error() 方法

image.png

4.stack 获取调用堆栈

神器,用于线上环境,我们看下调用链路,到底某个方法走到了没有走到, 命令 stack 类, 方法

执行 stack com.jzj.jvmtest.font.TestController getScore

然后访问请求 curl 127.0.0.1:8078/print?score=“66” 监控此方法的调用堆栈

[arthas@13016]$ stack com.jzj.jvmtest.font.TestController getScore
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 33 ms, listenerId: 9
ts=2023-05-07 13:13:28;thread_name=http-nio-8078-exec-8;id=31;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@7e22550a
    @com.jzj.jvmtest.font.TestController.getScore()
        at jdk.internal.reflect.GeneratedMethodAccessor26.invoke(null:-1)
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:568)

5.minitor 监控类方法的 成功率,失败次数等

minitor 适用于监控类 方法的 成功率,失败率,等信息

监控项说明
timestamp时间戳
classJava类
method方法(构造方法、普通方法)
total方法调用次数
success方法成功次数
fail方法失败次数
rt方法平均RT
fail-rate方法失败率

monitor -c 5 com.jzj.jvmtest.font.TestController getScore 表示每 5 秒,打印一次 TestController 的方法getScore的监控信息

**执行 minitor **

[arthas@13016]$ monitor -c 5 com.jzj.jvmtest.font.TestController getScore
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 37 ms, listenerId: 10
 timestamp                  class                                   method                                   total        success       fail         avg-rt(ms)    fail-rate
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 2023-05-07 13:23:49        com.jzj.jvmtest.font.TestController     getScore                                 1            1             0            0.32          0.00%

 timestamp                  class                                   method                                   total        success       fail         avg-rt(ms)    fail-rate
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 2023-05-07 13:23:54        com.jzj.jvmtest.font.TestController     getScore                                 1            1             0            0.22          0.00%

 timestamp                  class                                   method                                   total        success       fail         avg-rt(ms)    fail-rate
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 2023-05-07 13:23:59        com.jzj.jvmtest.font.TestController     getScore                                 3            3             0            0.24          0.00%

 timestamp                  class                                   method                                   total        success       fail         avg-rt(ms)    fail-rate
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 2023-05-07 13:24:04        com.jzj.jvmtest.font.TestController     getScore                                 2            2             0            0.27          0.00%

 timestamp                  class                                   method                                   total        success       fail         avg-rt(ms)    fail-rate

监控结果如下 ,每5秒一次监控统计信息

image.png


至此我们已经学会了大部分Arthas的监控命令,watch查看类方法输入输出信息,trace链路追踪排查最耗时的方法调用,stack打印类方法调用堆栈信息,minitor监控方法调用信息