Java工具arthas的使用--结合实际工作

Posted master-dragon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java工具arthas的使用--结合实际工作相关的知识,希望对你有一定的参考价值。

目录

安装使用

https://arthas.aliyun.com/zh-cn/

sc 查看JVM已加载的类信息

“Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,这个命令支持的参数有 [d]、[E]、[f] 和 [x:]。

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
[d]输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。如果一个类被多个ClassLoader所加载,则会出现多次
[E]开启正则表达式匹配,默认为通配符匹配
[f]输出当前类的成员变量信息(需要配合参数-d一起使用)
[x:]指定输出静态变量时属性的遍历深度,默认为 0,即直接使用 toString 输出
[c:]指定class的 ClassLoader 的 hashcode
[classLoaderClass:]指定执行表达式的 ClassLoader 的 class name
[n:]具有详细信息的匹配类的最大数量(默认为100)

sm(查看已加载类的方法信息)

“Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。

sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。

参数
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
[d] 展示每个方法的详细信息
[E] 开启正则表达式匹配,默认为通配符匹配
[c:] 指定class的 ClassLoader 的 hashcode
[classLoaderClass:] 指定执行表达式的 ClassLoader 的 class name
[n:] 具有详细信息的匹配类的最大数量(默认为100)

thread命令

查看所有线程

dashboard命令

thread, memory, gc, runtime相关信息

trace

方法内部调用路径,并输出方法路径上的每个节点上耗时;
* trace 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路; 3.3.0 版本后,可以使用动态Trace功能,不断增加新的匹配类
* 如果方法调用的次数很多,那么可以用-n参数指定捕捉结果的次数
* --skipJDKMethod : skip jdk method trace, default value true.
* 使用 --exclude-class-pattern 参数可以排除掉指定的类

多层调用trace


附代码

@GetMapping(value = "/test-cost")
   public String getTestCost() 
       return cost1s();
   

   private String cost1s()
       try 
           TimeUnit.SECONDS.sleep(1);
       catch (Exception e)

       
       return cost2s();
   

   private String cost2s()
       try 
           TimeUnit.SECONDS.sleep(2);
       catch (Exception e)

       
       return cost3s();
   

   private String cost3s()
       try 
           TimeUnit.SECONDS.sleep(3);
       catch (Exception e)

       
       return "3s";
   

特定调用参数trace

eg: trace如下方法

  • trace id = 2 的调用
trace com.example.demo.control.TestControl getTestParam "params[0]=2"
  • trace id > 129 的调用
 trace com.example.demo.control.TestControl getTestParam "params[0]>129"
  • trace id > 129 && id < 133 的调用
trace com.example.demo.control.TestControl getTestParam "params[0]>129 && params[0]<133"
  • trace id > 129 && name="aa"的调用
 trace com.example.demo.control.TestControl getTestParam "params[0]>129 && params[1].equals('aa')"

多方法&多层调用


附代码

    @GetMapping(value = "/test-cost")
    public Integer getTestCost() 
        int a = cost1();
        int b = cost2();
        int c = cost3();
        return a + b + c;
    

    private Integer cost1()
        try 
            TimeUnit.MILLISECONDS.sleep(100);
        catch (Exception e)

        
        return 100 + cost11();
    

    private Integer cost2()
        try 
            TimeUnit.MILLISECONDS.sleep(200);
        catch (Exception e)

        
        return 200 + cost22();
    

    private Integer cost3()
        try 
            TimeUnit.MILLISECONDS.sleep(300);
        catch (Exception e)

        
        return 300;
    

    private Integer cost11()
        try 
            TimeUnit.MILLISECONDS.sleep(50);
        catch (Exception e)

        
        return 50;
    

    private Integer cost22()
        try 
            TimeUnit.MILLISECONDS.sleep(30);
        catch (Exception e)

        
        return 30;
    

stack

  • 输出当前方法被调用的调用路径

很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。

[arthas@14273]$ stack com.example.demoapi.control.TestControl cost11
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 45 ms, listenerId: 4
ts=2021-03-27 12:25:34;thread_name=http-nio-8080-exec-5;id=17;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@11bd803
   @com.example.demoapi.control.TestControl.cost11()
       at com.example.demoapi.control.TestControl.cost1(TestControl.java:35)
       at com.example.demoapi.control.TestControl.getTestCost(TestControl.java:23)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-2)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:498)
       at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
       at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
       at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
       at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
       at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
       at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
       at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
       at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
       at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
       at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
       at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
       at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
       at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
       at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
       at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
       at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
       at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
       at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
       at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
       at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
       at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
       at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
       at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
       at java.lang.Thread.run(Thread.java:748)

watch

方法执行数据观测: 让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。

  • watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后

  • 4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出

  • 这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参

  • 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在

  • watch com.example.demoapi.control.UserControl getById "params,returnObj" -x 2

  • 只观察方法入参

watch com.example.demoapi.control.UserControl getById "params,returnObj" -b

ognl

学习文档:https://arthas.aliyun.com/doc/ognl.html

  • 获取静态变量
[arthas@31512]$ ognl '@com.example.demoapi.control.TestControl@CNT'
@Integer[1024]
  • 执行多个表达式,并对结果对象进行展开
[arthas@31195]$ ognl '#value1=@com.example.demoapi.util.SpringContextUtils@getBean("testControl"),#value1.ognlTest("hello")' -x 1
@ArrayList[
    @ResponseData[com.example.demoapi.ResponseData@5b061dae],
    @ResponseData[com.example.demoapi.ResponseData@699479c4],
    @ResponseData[com.example.demoapi.ResponseData@56997e18],
]
[arthas@31195]$ ognl '#value1=@com.example.demoapi.util.SpringContextUtils@getBean("testControl"),#value1.ognlTest("hello")' -x 2
@ArrayList[
    @ResponseData[
        code=@String[[12]深入浅出工作开源框架Camunda: 使用Arthas监控Camunda

Java应用线上问题诊断工具Alibaba Arthas

Arthas(阿尔萨斯)-java诊断工具-----来源于网络

Alibaba Java诊断工具Arthas之快速安装和简单使用

Arthas在线java进程诊断工具 在线调试神器

Arthas使用教程 阿里巴巴开源项目史上最强java线上诊断工具