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