Alibaba Arthas 使用学习之路,最详细讲解

1.Arthas 是什么?

   Arthas 是Alibaba 开发得一款java诊断工具,可以帮我们查看jvm使用情况,查看线程数,排除阻塞线程;监听类和方法得调用次数,失败次数(失败率),执行时常;监听方法得入参,出参,异常信息;快速反编译查看源码,并修改源码,编译运行;查看堆栈信息等。

2.这里列出一些常用命令并一一讲解

   最常用得命令:dashboard,thread,jvm,sc,sm,jad,mc,redefine,monitor,watch。官方地址:https://alibaba.github.io/arthas/monitor.html

dashboard

dashboard

   dashboard 当前系统的实时数据面板,按 ctrl+c 退出,当运行在Ali-tomcat时,会显示当前tomcat的实时信息,如HTTP请求的qps, rt, 错误数, 线程池信息等等。
   数据说明如下:

  • ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
  • NAME: 线程名
  • GROUP: 线程组名
  • PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
  • STATE: 线程的状态
  • CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
  • TIME: 线程运行总时间,数据格式为 分:秒
  • INTERRUPTED: 线程当前的中断位状态
  • DAEMON: 是否是守护线程

thread

   查看当前线程信息,查看线程的堆栈
   参数说明:id(线程id),[n:](指定最忙的前N个线程并打印堆栈),[b](找出当前阻塞其他线程的线程),[i](指定cpu占比统计的采样间隔,单位为毫秒,建议5000)
   示例: thread -n 3 找出前3个线程的堆栈信息

$ thread -n 3
"as-command-execute-daemon" Id=58 cpuUsage=76% RUNNABLE
    at [email protected]/sun.management.ThreadImpl.dumpThreads0(Native Method)
    at [email protected]/sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:466)
    at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:133)
    at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:79)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
    at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:370)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at [email protected]/java.lang.Thread.run(Thread.java:835)

    Number of locked synchronizers = 1
    - java.util.concurrent.ThreadPoolExecutor$Worker@7808db3c


"NioBlockingSelector.BlockPoller-1" Id=24 cpuUsage=17% RUNNABLE (in native)
    at [email protected]/sun.nio.ch.EPoll.wait(Native Method)
    at [email protected]/sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:120)
    at [email protected]/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:124)
    -  locked sun.nio.ch.Util$2@1a574b17
    -  locked sun.nio.ch.EPollSelectorImpl@7b0d44f5
    at [email protected]/sun.nio.ch.SelectorImpl.select(SelectorImpl.java:136)
    at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:304)


"http-nio-8087-ClientPoller-1" Id=36 cpuUsage=5% RUNNABLE (in native)
    at [email protected]/sun.nio.ch.EPoll.wait(Native Method)
    at [email protected]/sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:120)
    at [email protected]/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:124)
    -  locked sun.nio.ch.Util$2@703ba4c0
    -  locked sun.nio.ch.EPollSelectorImpl@6a6a92bd
    at [email protected]/sun.nio.ch.SelectorImpl.select(SelectorImpl.java:136)
    at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:743)
    at [email protected]/java.lang.Thread.run(Thread.java:835)


Affect(row-cnt:0) cost in 131 ms.

   示例:thread 打出所有运行线程

$ thread
Threads Total: 37, NEW: 0, RUNNABLE: 14, BLOCKED: 0, WAITING: 17, TIMED_WAITING: 6, TERMINATED: 0                                                                                                                                       
ID                 NAME                                                      GROUP                                  PRIORITY           STATE               %CPU               TIME               INTERRUPTED         DAEMON             
59                 as-command-execute-daemon                                 system                                 10                 RUNNABLE            100                0:0                false               true               
42                 AsyncAppender-Worker-arthas-cache.result.AsyncAppender    system                                 9                  WAITING             0                  0:0                false               true               
40                 Attach Listener                                           system                                 9                  RUNNABLE            0                  0:0                false               true               
14                 Catalina-utility-1                                        main                                   1                  WAITING             0                  0:1                false               false              
15                 Catalina-utility-2                                        main                                   1                  TIMED_WAITING       0                  0:0                false               false              
10                 Common-Cleaner                                            InnocuousThreadGroup                   8                  TIMED_WAITING       0                  0:0                false               true               
39                 DestroyJavaVM                                             main                                   5                  RUNNABLE            0                  0:12               false               false              
3                  Finalizer                                                 system                                 8                  WAITING             0                  0:0                false               true               
19                 MQTT Call: mqttId_inbound                                 main                                   5                  WAITING             0                  0:0                false               false              
23                 MQTT Ping: mqttId_inbound                                 main                                   5                  TIMED_WAITING       0                  0:0                false               false              
20                 MQTT Rec: mqttId_inbound                                  main                                   5                  RUNNABLE            0                  0:0                false               false              
21                 MQTT Snd: mqttId_inbound                                  main                                   5                  WAITING             0                  0:0                false               false              
24                 NioBlockingSelector.BlockPoller-1                         main                                   5                  RUNNABLE            0                  0:0                false               true               
2                  Reference Handler                                         system                                 10                 RUNNABLE            0                  0:0                false               true               
4                  Signal Dispatcher                                         system                                 9                  RUNNABLE            0                  0:0                false               true               
16                 container-0                                               main                                   5                  TIMED_WAITING       0                  0:0                false               false              
37                 http-nio-8087-Acceptor-0                                  main                                   5                  RUNNABLE            0                  0:0                false               true               
35                 http-nio-8087-ClientPoller-0                              main                                   5                  RUNNABLE            0                  0:0                false               true               
36                 http-nio-8087-ClientPoller-1                              main                                   5                  RUNNABLE            0                  0:0                false               true               
25                 http-nio-8087-exec-1                                      main                                   5                  WAITING             0                  0:0                false               true               
34                 http-nio-8087-exec-10                                     main                                   5                  WAITING             0                  0:0                false               true               
26                 http-nio-8087-exec-2                                      main                                   5                  WAITING             0                  0:0                false               true               
27                 http-nio-8087-exec-3                                      main                                   5                  WAITING             0                  0:0                false               true               
28                 http-nio-8087-exec-4                                      main                                   5                  WAITING             0                  0:0                false               true               
29                 http-nio-8087-exec-5                                      main                                   5                  WAITING             0                  0:0                false               true               
30                 http-nio-8087-exec-6                                      main                                   5                  WAITING             0                  0:0                false               true               
31                 http-nio-8087-exec-7                                      main                                   5                  WAITING             0                  0:0                false               true               
32                 http-nio-8087-exec-8                                      main                                   5                  WAITING             0                  0:0                false               true               
33                 http-nio-8087-exec-9                                      main                                   5                  WAITING             0                  0:0                false               true               
44                 job-timeout                                               system                                 9                  TIMED_WAITING       0                  0:0                false               true               
45                 nioEventLoopGroup-2-1                                     system                                 10                 RUNNABLE            0                  0:0                false               false              
49                 nioEventLoopGroup-2-2                                     system                                 10                 RUNNABLE            0                  0:1                false               false              
53                 nioEventLoopGroup-2-3                                     system                                 10                 RUNNABLE            0                  0:0                false               false              
46                 nioEventLoopGroup-3-1                                     system                                 10                 RUNNABLE            0                  0:0                false               false              
22                 pool-2-thread-4                                           main                                   5                  WAITING             0                  0:0                false               false              
47                 pool-3-thread-1                                           system                                 5                  TIMED_WAITING       0                  0:0                false               false              
48                 pool-4-thread-1                                           system                                 5                  WAITING             0                  0:0                false               false              
Affect(row-cnt:0) cost in 113 ms.

   示例:thread 20 查看线程id为20的堆栈信息

$ thread 20
"MQTT Rec: mqttId_inbound" Id=20 RUNNABLE (in native)
    at [email protected]/java.net.SocketInputStream.socketRead0(Native Method)
    at [email protected]/java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
    at [email protected]/java.net.SocketInputStream.read(SocketInputStream.java:168)
    at [email protected]/java.net.SocketInputStream.read(SocketInputStream.java:140)
    at [email protected]/java.net.SocketInputStream.read(SocketInputStream.java:200)
    at [email protected]/java.io.DataInputStream.readByte(DataInputStream.java:270)
    at org.eclipse.paho.client.mqttv3.internal.wire.MqttInputStream.readMqttWireMessage(MqttInputStream.java:92)
    at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:133)
    at [email protected]/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at [email protected]/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at [email protected]/java.lang.Thread.run(Thread.java:835)

    Number of locked synchronizers = 1
    - java.util.concurrent.ThreadPoolExecutor$Worker@79cf8c25

Affect(row-cnt:0) cost in 33 ms.

   示例:thread -b 找出阻塞其他线程的线程

$ thread -b
No most blocking thread found!
Affect(row-cnt:0) cost in 43 ms.

   示例:thread -n 3 -i 5000 阻塞指定5秒后收到前3线程的堆栈信息

$ thread -n 3  -i 5000
"Catalina-utility-1" Id=14 cpuUsage=21% TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@72b49c8
    at [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@72b49c8
    at [email protected]/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:235)
    at [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2123)
    at [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
    at [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1054)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1114)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at [email protected]/java.lang.Thread.run(Thread.java:835)


"http-nio-8087-ClientPoller-1" Id=36 cpuUsage=14% RUNNABLE (in native)
    at [email protected]/sun.nio.ch.EPoll.wait(Native Method)
    at [email protected]/sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:120)
    at [email protected]/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:124)
    -  locked sun.nio.ch.Util$2@703ba4c0
    -  locked sun.nio.ch.EPollSelectorImpl@6a6a92bd
    at [email protected]/sun.nio.ch.SelectorImpl.select(SelectorImpl.java:136)
    at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:743)
    at [email protected]/java.lang.Thread.run(Thread.java:835)


"as-command-execute-daemon" Id=62 cpuUsage=10% RUNNABLE
    at [email protected]/sun.management.ThreadImpl.dumpThreads0(Native Method)
    at [email protected]/sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:466)
    at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:133)
    at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:79)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
    at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:370)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at [email protected]/java.lang.Thread.run(Thread.java:835)

    Number of locked synchronizers = 1
    - java.util.concurrent.ThreadPoolExecutor$Worker@2d2909be


Affect(row-cnt:0) cost in 5045 ms.

jvm

   查看当前JVM信息,这里只拿部分信息来说

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 THREAD                                                                                                                                                                                                                                 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 COUNT                                                             37                                                                                                                                                                   
 DAEMON-COUNT                                                      22                                                                                                                                                                   
 PEAK-COUNT                                                        38                                                                                                                                                                   
 STARTED-COUNT                                                     55                                                                                                                                                                   
 DEADLOCK-COUNT                                                    0                                                                                                                                                                    
                                                                                                                                                                                                                                        
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 FILE-DESCRIPTOR                                                                                                                                                                                                                        
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 MAX-FILE-DESCRIPTOR-COUNT                                         -1                                                                                                                                                                   
 OPEN-FILE-DESCRIPTOR-COUNT                                        -1         

   THREAD 相关

  • COUNT: JVM当前活跃的线程数
  • DAEMON-COUNT: JVM当前活跃的守护线程数
  • PEAK-COUNT: 从JVM启动开始曾经活着的最大线程数
  • STARTED-COUNT: 从JVM启动开始总共启动过的线程次数
  • DEADLOCK-COUNT: JVM当前死锁的线程数

   FILE-DESCRIPTOR 相关

  • MAX-FILE-DESCRIPTOR-COUNT:JVM进程最大可以打开的文件描述符数
  • OPEN-FILE-DESCRIPTOR-COUNT:JVM当前打开的文件描述符数

sc

   查看JVM已加载的类信息,
   参数说明:lass(包名+类名),method(方法名),[d](输出详细信息),[E](开启正则表达式匹配,默认为通配符匹配),[f](输出当前类的成员变量信息(需要配合参数-d一起使用)),[x:](指定输出静态变量时属性的遍历深度,默认为 0,即直接使用 toString 输出)
   class-pattern支持全限定名,如com.taobao.test.AAA,也支持com/taobao/test/AAA这样的格式,这样,我们从异常堆栈里面把类名拷贝过来的时候,不需要在手动把/替换为 . 啦。
   示例:sc com.cloud*

$ sc com.cloud*
com.cloud.mqtt.MqttApplication
com.cloud.mqtt.MqttApplication$$EnhancerBySpringCGLIB$$b4fbeb8a
com.cloud.mqtt.mqtt.MqttConfig
com.cloud.mqtt.mqtt.MqttConfig$$EnhancerBySpringCGLIB$$d1953d4e
com.cloud.mqtt.mqtt.MqttConfig$$EnhancerBySpringCGLIB$$d1953d4e$$FastClassBySpringCGLIB$$69e081d8
com.cloud.mqtt.mqtt.MqttConfig$$FastClassBySpringCGLIB$$bf72748c
com.cloud.mqtt.mqtt.MqttConfig$1
com.cloud.mqtt.mqtt.MqttReceiveConfig
com.cloud.mqtt.mqtt.MqttReceiveConfig$$EnhancerBySpringCGLIB$$5631a71d
com.cloud.mqtt.mqtt.MqttSenderConfig
com.cloud.mqtt.mqtt.MqttSenderConfig$$EnhancerBySpringCGLIB$$3bfb2a03
com.cloud.mqtt.mqtt.Publisher
com.cloud.mqtt.web.MqttGateway
com.cloud.mqtt.web.TestController
com.sun.proxy.$Proxy65
Affect(row-cnt:15) cost in 20 ms.

   示例:sc -d -f com.cloud.mqtt.web.TestController 打印类的信息以及字段的信息

$ sc -d -f com.cloud.mqtt.web.TestController
 class-info        com.cloud.mqtt.web.TestController                                                                                                                                                                                    
 code-source       file:/home/fengqianrun/opt/server/mqtt-0.0.1.jar!/BOOT-INF/classes!/                                                                                                                                                 
 name              com.cloud.mqtt.web.TestController                                                                                                                                                                                    
 isInterface       false                                                                                                                                                                                                                
 isAnnotation      false                                                                                                                                                                                                                
 isEnum            false                                                                                                                                                                                                                
 isAnonymousClass  false                                                                                                                                                                                                                
 isArray           false                                                                                                                                                                                                                
 isLocalClass      false                                                                                                                                                                                                                
 isMemberClass     false                                                                                                                                                                                                                
 isPrimitive       false                                                                                                                                                                                                                
 isSynthetic       false                                                                                                                                                                                                                
 simple-name       TestController                                                                                                                                                                                                       
 modifier          public                                                                                                                                                                                                               
 annotation        org.springframework.web.bind.annotation.RestController,org.springframework.web.bind.annotation.RequestMapping                                                                                                        
 interfaces                                                                                                                                                                                                                             
 super-class       +-java.lang.Object                                                                                                                                                                                                   
 class-loader      +-org.springframework.boot.loader.LaunchedURLClassLoader@439f5b3d                                                                                                                                                    
                     +-jdk.internal.loader.ClassLoaders$AppClassLoader@5bc2b487                                                                                                                                                         
                       +-jdk.internal.loader.ClassLoaders$PlatformClassLoader@75d2da2d                                                                                                                                                  
 classLoaderHash   439f5b3d                                                                                                                                                                                                             
 fields            modifier  private                                                                                                                                                                                                    
                   type      com.cloud.mqtt.web.MqttGateway                                                                                                                                                                                                      
                   name      mqttGateway                                                                                                                                                                                                
                   annotationjavax.annotation.Resource                                                                                                                                                                                  
                                                                                                                                                                                                                                        

Affect(row-cnt:1) cost in 15 ms.

sm

   查看已加载类的方法信息,命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。
   参数说明:class(包名+类名),method(方法名称),[d](展示每个方法的详细信息),[E](开启正则表达式匹配,默认为通配符匹配)
   示例:sm com.cloud.mqtt.web.TestController 查询TestController下的所有方法

$ sm  com.cloud.mqtt.web.TestController
com.cloud.mqtt.web.TestController ()V
com.cloud.mqtt.web.TestController test(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
com.cloud.mqtt.web.TestController sendMqtt(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
com.cloud.mqtt.web.TestController sendTest(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
Affect(row-cnt:4) cost in 12 ms.

   示例:sm -d com.cloud.mqtt.web.TestController test 查询TestController下的test方法详情

$ sm -d com.cloud.mqtt.web.TestController test
 declaring-class  com.cloud.mqtt.web.TestController                                                                                                                                                                                     
 method-name      test                                                                                                                                                                                                                  
 modifier         public                                                                                                                                                                                                                
 annotation       org.springframework.web.bind.annotation.GetMapping                                                                                                                                                                    
 parameters       java.lang.String                                                                                                                                                                                                      
                  java.lang.String                                                                                                                                                                                                      
 return           java.lang.String                                                                                                                                                                                                      
 exceptions                                                                                                                                                                                                                             

Affect(row-cnt:1) cost in 13 ms.

jad

   jad 反编译指定已加载类得源码,jad 在Arthas Console上,反编译出来得源码是带语法高亮得,阅读方便,当然反编译出来得java代码可能会存在语法错误,但不影响你的进行阅读。
   参数说明:class(包名+类名),[c:](类所属ClassLoader得hashcode),[E](开启正则表达匹配,默认通配符)
   示例:反编译 com.cloud.mqtt.web.TestController

$ jad com.cloud.mqtt.web.TestController

ClassLoader:                                                                                                                                                                                                                            
+-org.springframework.boot.loader.LaunchedURLClassLoader@439f5b3d                                                                                                                                                                       
  +-jdk.internal.loader.ClassLoaders$AppClassLoader@5bc2b487                                                                                                                                                                            
    +-jdk.internal.loader.ClassLoaders$PlatformClassLoader@75d2da2d                                                                                                                                                                     

Location:                                                                                                                                                                                                                               
file:/home/fengqianrun/opt/server/mqtt-0.0.1.jar!/BOOT-INF/classes!/                                                                                                                                                                    

/*
 * Decompiled with CFR 0_132.
 * 
 * Could not load the following classes:
 *  com.cloud.mqtt.web.MqttGateway
 *  javax.annotation.Resource
 *  org.springframework.web.bind.annotation.GetMapping
 *  org.springframework.web.bind.annotation.RequestMapping
 *  org.springframework.web.bind.annotation.RequestParam
 *  org.springframework.web.bind.annotation.RestController
 */
package com.cloud.mqtt.web;

import com.cloud.mqtt.web.MqttGateway;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value={"/test"})
public class TestController {
    @Resource
    private MqttGateway mqttGateway;

    @GetMapping(value={"/"})
    public String test(String a, String b) {
        String rt = a + b;
        return rt;
    }

    @GetMapping(value={"/send"})
    public String sendMqtt(@RequestParam(value="data") String data, @RequestParam(value="topic") String topic) {
        String rt = "sendMqtt";
        return rt;
    }

    @GetMapping(value={"/sendTest"})
    public String sendTest(@RequestParam(value="data") String data, @RequestParam(value="topic") String topic) {
        String rt = "sendMqtt";
        return "OK";
    }
}

Affect(row-cnt:1) cost in 394 ms.

   示例:反编译 com.cloud.mqtt.web.TestController test方法

$ jad com.cloud.mqtt.web.TestController test

ClassLoader:                                                                                                                                                                                                                            
+-org.springframework.boot.loader.LaunchedURLClassLoader@439f5b3d                                                                                                                                                                       
  +-jdk.internal.loader.ClassLoaders$AppClassLoader@5bc2b487                                                                                                                                                                            
    +-jdk.internal.loader.ClassLoaders$PlatformClassLoader@75d2da2d                                                                                                                                                                     

Location:                                                                                                                                                                                                                               
file:/home/fengqianrun/opt/server/mqtt-0.0.1.jar!/BOOT-INF/classes!/                                                                                                                                                                    

@GetMapping(value={"/"})
public String test(String a, String b) {
    String rt = a + b;
    return rt;
}

Affect(row-cnt:1) cost in 67 ms.

mc

   内存编译器,编译.java文件生成.class文件。编译生成.class之后们,可以节后 redefine 命令实现热更新代码。
   参数说明:[c:](指定classloader),[d](指定输出目录)

mc /tmp/Test.java 编译Test.java文件
mc -c 327a647b /tmp/Test.java 指定classloader编译
mc -d /tmp/output /tmp/ClassA.java /tmp/ClassB.java 编译到指定目录

redefine

   加载外部的 .class 文件到redefine jvm已加载的类。
   redefine后的原来的类不能恢复,redefine有可能失败(比如增加了新的field),参考jdk本身的文档。
   参数说明:[c:](ClassLoader的hashcode),[p:](外部的.class文件的完整路径,支持多个)

redefine /tmp/Test.class
结合 jad/mc 命令使用:
jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java
mc /tmp/UserController.java -d /tmp
redefine /tmp/com/example/demo/arthas/user/UserController.class
- jad命令反编译,然后可以用其它编译器,比如vim来修改源码
- mc命令来内存编译修改过的代码
- 用redefine命令加载新的字节码

   redefine的限制,不允许新增加field/method,正在跑的函数,没有退出不能生效,比如下面新增加的System.out.println,只有run()函数里的会生效。

monitor

   monitor 方法监控执行,是一个非实时得返回命令,意思就是可以一直监控某一个方法,直到你按 ctrl+c结束为止。
   监控得信息包括:timestamp(时间戳),class(java类),method(方法,包括构造方法和普通方法),total(调用次数),success(成功次数),fail(失败次数),rt(平均RT),fail-rate(失败率)。
   方法参数说明:class(包名+类名),method(方法名),[E](开启正则表达匹配,默认通配符),[c:](得到运行报告得间隔时间,默认是120秒)

$ monitor -c 5 com.cloud.mqtt.web.TestController test
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 60 ms.
 timestamp            class                              method  total  success  fail  avg-rt(ms)  fail-rate                                                                                                                            
-------------------------------------------------------------------------------------------------------------                                                                                                                           
 2019-08-19 14:29:03  com.cloud.mqtt.web.TestController  test    6      6        0     0.34        0.00%                                                                                                                                

 timestamp            class                              method  total  success  fail  avg-rt(ms)  fail-rate                                                                                                                            
-------------------------------------------------------------------------------------------------------------                                                                                                                           
 2019-08-19 14:29:08  com.cloud.mqtt.web.TestController  test    1      1        0     0.09        0.00%                                                                                                                                

 timestamp            class                              method  total  success  fail  avg-rt(ms)  fail-rate                                                                                                                            
-------------------------------------------------------------------------------------------------------------                                                                                                                           
 2019-08-19 14:29:13  com.cloud.mqtt.web.TestController  test    0      0        0     0.00        0.00%                                                                                                                                

 timestamp            class                              method  total  success  fail  avg-rt(ms)  fail-rate                                                                                                                            
-------------------------------------------------------------------------------------------------------------                                                                                                                           
 2019-08-19 14:29:18  com.cloud.mqtt.web.TestController  test    0      0        0     0.00        0.00%            

  我得类 com.cloud.mqtt.web.TestController ,方法为 test ,-c 5 得意思就是每5秒打印一次。

watch

   watch 方法执行数据观测。
   参数说明:class(类名表达式匹配),method(方法名表达式匹配),express(观察表达式),condition-express(条件表达式),[b](在方法调用之前观察),[e](在方法异常之后观察),[s](在方法返回之后观察),[f](在方法结束之后(正常返回和异常返回)观察),[E](开启正则表达式匹配,默认为通配符匹配),[x:](指定输出结果的属性遍历深度,默认为 1)
   特别说明:

  • watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后
  • 4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
  • 这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参
  • 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在
curl "http://192.168.15.130:8087/test/?a=1&b=3" ,-x 2的意思是,是否深度解析参数,如果你的参数是一个对象,不深度解析,你看到的只是对象地址,深度解析的值,跟你参数所嵌套层数有关。
$ watch com.cloud.mqtt.web.TestController  test "{params,returnObj}" -x 2
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 41 ms.
ts=2019-08-19 17:02:09; [cost=0.241819ms] result=@ArrayList[
    @Object[][
        @String[1],
        @String[3],
    ],
    @String[13],
]

-b 意思是解析入参,-s解析出参, -n 2执行两次的意思,2次完则结束。结果的输出顺序和事件发生的先后顺序一致,和命令中 -s -b 的顺序无关。
$ watch com.cloud.mqtt.web.TestController  test "{params,returnObj}" -x 2 -b  -s -n 2
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 46 ms.
ts=2019-08-19 17:06:21; [cost=0.006941ms] result=@ArrayList[
    @Object[][
        @String[1],
        @String[3],
    ],
    null,
]
ts=2019-08-19 17:06:21; [cost=0.945661ms] result=@ArrayList[
    @Object[][
        @String[1],
        @String[3],
    ],
    @String[13],
]
Command execution times exceed limit: 2, so command will exit. You can set it with -n option.

条件表达式,第一个传参大于5才执行
$ watch com.cloud.mqtt.web.TestController  test "{params[0],returnObj}" "params[0] > 5"
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 39 ms.
ts=2019-08-19 17:21:58; [cost=0.183399ms] result=@ArrayList[
    @String[6],
    @String[63],
]

异常信息举例:-e 表示抛出异常时才触发,express中,表示异常信息的变量是throwExp
$ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 62 ms.
ts=2018-12-03 19:38:00; [cost=1.414993ms] result=@ArrayList[
    @Integer[-1120397038],
    java.lang.IllegalArgumentException: number is: -1120397038, need >= 2
    at demo.MathGame.primeFactors(MathGame.java:46)
    at demo.MathGame.run(MathGame.java:24)
    at demo.MathGame.main(MathGame.java:16),
]

按照耗时进行过滤:#cost>200(单位是ms)表示只有当耗时大于200ms时才会输出,过滤掉执行时间小于200ms的调用
$ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2
$ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[
    @Object[][
        @Integer[2141897465],
    ],
    @ArrayList[
        @Integer[5],
        @Integer[428379493],
    ],
]

观察当前对象中的属性:如果想查看方法运行前后,当前对象中的属性,可以使用target关键字,代表当前对象,然后使用target.field_name访问当前对象的某个属性
$ watch com.cloud.mqtt.web.TestController  test 'target'
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 47 ms.
ts=2019-08-19 17:27:09; [cost=0.450697ms] result=@TestController[
    mqttGateway=@$Proxy65[gateway proxy for service interface [interface com.cloud.mqtt.web.MqttGateway]],
]

$ watch com.cloud.mqtt.web.TestController  test 'target.mqttGateway'
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 46 ms.
ts=2019-08-19 17:28:31; [cost=0.352704ms] result=@$Proxy65[
    m1=@Method[public boolean java.lang.Object.equals(java.lang.Object)],
    m10=@Method[public abstract boolean org.springframework.aop.framework.Advised.isExposeProxy()],
    m13=@Method[public abstract void org.springframework.aop.framework.Advised.addAdvisor(org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException],
    m7=@Method[public abstract boolean org.springframework.aop.framework.Advised.isProxyTargetClass()],
    m15=@Method[public abstract void org.springframework.aop.framework.Advised.removeAdvisor(int) throws org.springframework.aop.framework.AopConfigException],
    m23=@Method[public abstract java.lang.Class[] org.springframework.aop.framework.Advised.getProxiedInterfaces()],
    m5=@Method[public abstract int org.springframework.aop.framework.Advised.indexOf(org.springframework.aop.Advisor)],
    m22=@Method[public abstract org.springframework.aop.TargetSource org.springframework.aop.framework.Advised.getTargetSource()],
    m18=@Method[public abstract void org.springframework.aop.framework.Advised.addAdvice(int,org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException],
    m19=@Method[public abstract void org.springframework.aop.framework.Advised.addAdvice(org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException],
    m0=@Method[public native int java.lang.Object.hashCode()],
    m24=@Method[public abstract boolean org.springframework.aop.framework.Advised.isInterfaceProxied(java.lang.Class)],
    m20=@Method[public abstract boolean org.springframework.aop.framework.Advised.removeAdvice(org.aopalliance.aop.Advice)],
    m9=@Method[public abstract void org.springframework.aop.framework.Advised.setExposeProxy(boolean)],
    m8=@Method[public abstract void org.springframework.aop.framework.Advised.setTargetSource(org.springframework.aop.TargetSource)],
    m2=@Method[public java.lang.String java.lang.Object.toString()],
    m26=@Method[public abstract java.lang.Class org.springframework.aop.TargetClassAware.getTargetClass()],
    m14=@Method[public abstract void org.springframework.aop.framework.Advised.addAdvisor(int,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException],
    m27=@Method[public abstract java.lang.Class org.springframework.core.DecoratingProxy.getDecoratedClass()],
    m16=@Method[public abstract boolean org.springframework.aop.framework.Advised.removeAdvisor(org.springframework.aop.Advisor)],
    m4=@Method[public abstract int org.springframework.aop.framework.Advised.indexOf(org.aopalliance.aop.Advice)],
    m6=@Method[public abstract boolean org.springframework.aop.framework.Advised.isFrozen()],
    m17=@Method[public abstract boolean org.springframework.aop.framework.Advised.replaceAdvisor(org.springframework.aop.Advisor,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException],
    m11=@Method[public abstract void org.springframework.aop.framework.Advised.setPreFiltered(boolean)],
    m3=@Method[public abstract void com.cloud.mqtt.web.MqttGateway.sendToMqtt(java.lang.String,java.lang.String)],
    m21=@Method[public abstract java.lang.String org.springframework.aop.framework.Advised.toProxyConfigString()],
    m25=@Method[public abstract org.springframework.aop.Advisor[] org.springframework.aop.framework.Advised.getAdvisors()],
    m12=@Method[public abstract boolean org.springframework.aop.framework.Advised.isPreFiltered()],
]

你可能感兴趣的:(Alibaba Arthas 使用学习之路,最详细讲解)