Alibaba Arthas is a tool for monitoring and profiling Java applications. The feature is that it can be used without changing the settings of the monitored application or restarting it. There are many things that Arthas can do, and I used to use only some of the functions, but when I looked it up again, I found that I could do various things, so I would like to touch on the introduction.
To install and run Arthas, just run the following command (for Linux): Arthas itself is a java application, so it can be run in other environments.
$ curl -O https://arthas.aliyun.com/arthas-boot.jar
$ java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.4.0
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 631 org.logstash.Logstash
  [2]: 3834 camel-springboot-rest-test-0.0.1-SNAPSHOT.jar
In the two lines below, the running java application is displayed, so enter the process to be monitored.
2 ★ This time"2"Enter
[INFO] arthas home: /root/.arthas/lib/3.4.1/arthas
[INFO] Try to attach process 3834
[INFO] Attach process 3834 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.1                                                                 
pid       3834                                                                  
time      2020-09-12 01:17:02    
With the dashboard command, you can execute a dashboard that can display the thread list of the java application, heap usage status, etc. Press "q" to exit.
[arthas@3834]$ dashboard

You can display a list of threads with the thread command.

You can display the information of a specific thread by using [Thread ID] from the above list.
[arthas@3834]$ thread 156
"Camel (camel-1) thread #1 - ThroughputLogger" Id=156 TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@74abfe92
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@74abfe92
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Shows the stack trace of the method.
stack [class] [Method]
[arthas@4939]$ stack mkyz08.example.HelloRestController hello
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 29 ms, listenerId: 5
ts=2020-09-12 01:47:58;thread_name=http-nio-8080-exec-8;id=18;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@710f4dc7
    @mkyz08.example.HelloRestController.hello()
        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:215)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:142)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
 
To limit the number of impressions, execute as follows.
stack [class] [Method] -n [Number of executions]
Monitor information such as method return values, exceptions, and parameters. It can be executed with the watch command.
watch [class] [Method] [Other options]
"{params, returnObj}" displays the return value and parameters after execution. "-x 2" is the display depth.
[arthas@4939]$ watch mkyz08.example.HelloRestController hello "{params,returnObj}" -x 2 
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 35 ms, listenerId: 19
ts=2020-09-12 05:24:36; [cost=1.155725ms] result=@ArrayList[
    @Object[][
        @String[hoge],
    ],
    @String[Hello World],
]
Use "{params, returnObj} -b" to display the return value and parameters before executing the method. Although the return value is specified, it will always be null because it has not been executed yet.
[arthas@4939]$ watch mkyz08.example.HelloRestController hello "{params,returnObj}" -x 2 -b
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 36 ms, listenerId: 20
ts=2020-09-12 05:25:06; [cost=0.03669ms] result=@ArrayList[
    @Object[][
        @String[hoge],
    ],
    null,
]
Display logger information with the logger command.
[arthas@4939]$ logger
 name                  ROOT                                                                                                      
 class                 ch.qos.logback.classic.Logger                                                                             
 classLoader           org.springframework.boot.loader.LaunchedURLClassLoader@685f4c2e                                           
 classLoaderHash       685f4c2e                                                                                                  
 level                 INFO                                                                                                      
 effectiveLevel        INFO                                                                                                      
 additivity            true                                                                                                      
 codeSource            jar:file:/root/camel-springboot-rest-test-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/logback-classic-1.2.3.jar!/    
 appenders             name            CONSOLE                                                                                   
                       class           ch.qos.logback.core.ConsoleAppender                                                       
                       classLoader     org.springframework.boot.loader.LaunchedURLClassLoader@685f4c2e                           
                       classLoaderHash 685f4c2e                                                                                  
                       target          System.out   
You can change the log level with the following command.
$ logger --name ROOT --level DEBUG
Update logger level success.
In case of Spring-Boot, it was necessary to specify the class loader with "-c".
$ logger --name ROOT --level DEBUG -c 685f4c2e
Update logger level success.
You can display MBean information with the mbean command.
[arthas@4939]$ mbean org.apache.camel:context=MyCamelRestApp,type=routes,* ExchangesCompleted
 OBJECT_NAME         org.apache.camel:context=MyCamelRestApp,type=routes,name="hello world route"                                
--------------------------------------------------------------------------------------------------                               
 NAME                VALUE                                                                                                       
--------------------------------------------------------------------------------------------------                               
 ExchangesCompleted  78                                                                                                          
You can get a heap dump with the heapdump command.
[arthas@4939]$ heapdump /tmp/dump.hprof
Dumping heap to /tmp/dump.hprof ...
Heap dump file created
If "--live" is specified, FullGC will be executed before the heap dump is acquired.
[arthas@4939]$ heapdump --live /tmp/dump_live.hprof
Dumping heap to /tmp/dump_live.hprof ...
Heap dump file created
async-profiler
Try profiler your application using async-profiler.
[arthas@4939]$ profiler start
Started [cpu] profiling
#Check the number of sample data acquisitions
[arthas@4939]$ profiler getSamples
2
#Check profiler status
[arthas@4939]$ profiler status
[perf] profiling is running for 19 seconds
[arthas@4939]$ profiler stop
OK
profiler output file: /root/arthas-output/20200912-022458.svg
If you stop the profiler with "profiler stop", the SVG file will be output. You can also output in HTML. The acquired Flame Graph is as follows.

You can trace method calls with the trace command. The trace also shows the execution time of each method, so you can use it to analyze which method is slower.
[arthas@4939]$ trace mkyz08.example.HelloRestController hello
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 72 ms, listenerId: 7
`---ts=2020-09-12 02:11:16;thread_name=http-nio-8080-exec-3;id=13;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@710f4dc7
    `---[1.01167ms] mkyz08.example.HelloRestController:hello()
        +---[0.130848ms] org.apache.camel.CamelContext:getEndpoint() #26
        `---[0.649678ms] org.apache.camel.ProducerTemplate:sendBody() #27
To limit the number of executions, execute as follows.
trace [class] [Method] -n [Number of executions]
If you want to extract only the methods that have been executed for the specified time (100ms in the example), execute as follows.
trace [class] [Method] '#cost>100'
Not only the trace command, but you can also use the grep command. For example, you can use it to filter by package.
[arthas@5716]$ trace mkyz08.example.HelloRestController hello | grep mkyz08
Press Q or Ctrl+C to abort.
    `---[1.459843ms] mkyz08.example.HelloRestController:hello()
        `---[0.066367ms] mkyz08.example.HelloRestController:add() #29
You can decompile the bytecode running in the JVM to the source code with the jad command. It can be used when you want to check the code of the method displayed by the trace and stack commands. It seems that it can be used for the purpose of checking whether other modified contents are applied to the server.
[arthas@4939]$ jad mkyz08.example.HelloRestController
ClassLoader:                                                                                                                     
+-org.springframework.boot.loader.LaunchedURLClassLoader@685f4c2e                                                                
  +-sun.misc.Launcher$AppClassLoader@70dea4e                                                                                     
    +-sun.misc.Launcher$ExtClassLoader@7c6908d7                                                                                  
Location:                                                                                                                        
file:/root/camel-springboot-rest-test-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/                                                     
/*
 * Decompiled with CFR.
 * 
 * Could not load the following classes:
 *  org.apache.camel.CamelContext
 *  org.apache.camel.Endpoint
 *  org.apache.camel.ProducerTemplate
 *  org.springframework.web.bind.annotation.RequestMapping
 *  org.springframework.web.bind.annotation.RequestMethod
 *  org.springframework.web.bind.annotation.RestController
 */
package mkyz08.example;
import javax.annotation.Resource;
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.ProducerTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value={"/spring"})
public class HelloRestController {
    @Resource
    private ProducerTemplate producer = null;
    @Resource
    private CamelContext context;
    @RequestMapping(method={RequestMethod.GET}, value={"/hello"}, produces={"text/plain"})
    public String hello(String msg) {
        Endpoint end = this.context.getEndpoint("seda:hello_world");
        this.producer.sendBody(end, (Object)msg);
        return "Hello World";
    }
}
Affect(row-cnt:1) cost in 505 ms.
Read the external class file and replace it with the class in the JVM.
Restrictions -Arguments, method names, and return values cannot be changed. -Class fields and methods cannot be changed, added, or deleted.
[arthas@5716]$ redefine /root/HelloRestController.class 
redefine success, size: 1, classes:
mkyz08.example.HelloRestController
Use the monitor command to monitor the number of method executions, average execution time, etc.
monitor [class] [Method]
An example of the execution result is as follows. Specify the display interval (seconds) with the "-c" option.
[arthas@5716]$ monitor -c 5 mkyz08.example.HelloRestController hello
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 35 ms, listenerId: 3
 timestamp           class                         method                       total     success   fail      avg-rt(m  fail-rat 
                                                                                                              s)        e        
---------------------------------------------------------------------------------------------------------------------------------
 2020-09-12 06:40:2  mkyz08.example.HelloRestCont  hello                        1         1         0         0.40      0.00%    
 4                   roller                                                                                                      
 timestamp           class                         method                       total     success   fail      avg-rt(m  fail-rat 
                                                                                                              s)        e        
---------------------------------------------------------------------------------------------------------------------------------
 2020-09-12 06:40:2  mkyz08.example.HelloRestCont  hello                        9         9         0         0.97      0.00%    
 9                   roller                                                                                                      
 timestamp           class                         method                       total     success   fail      avg-rt(m  fail-rat 
                                                                                                              s)        e        
---------------------------------------------------------------------------------------------------------------------------------
 2020-09-12 06:40:3  mkyz08.example.HelloRestCont  hello                        5         5         0         0.26      0.00%    
 4                   roller       
[arthas@4939]$ vmoption
 KEY                             VALUE                            ORIGIN                          WRITEABLE                      
---------------------------------------------------------------------------------------------------------------------------------
 HeapDumpBeforeFullGC            false                            DEFAULT                         true                           
 HeapDumpAfterFullGC             false                            DEFAULT                         true                           
 HeapDumpOnOutOfMemoryError      false                            DEFAULT                         true                           
~ Abbreviation ~
#When changing the value
[arthas@4939]$ vmoption PrintGC true
Successfully updated the vm option.
 NAME     BEFORE-VALUE  AFTER-VALUE                                                                                              
------------------------------------                                                                                             
 PrintGC  false         true   
help -Show help
cls -Clear the screen
session -View current session information
reset - resets enhanced classes. All enhanced classes will be reset to their original states. When Arthas server closes, all these enhanced classes will be reset too
version -View Arthas version
history -Display command execution history
quit -Close Arthas client
stop -Stop Arthas server
keymap -Show Arthas keyboard shortcuts
What I used to do with various tools can now be done with Arthas. Also, there are many commands other than the ones introduced this time, so please check them out on the official website. The web console also looked interesting.
Recommended Posts