❝
I believe that many people have such a feeling that their code in the development, testing environment run a stable stroke, can be on the line on the twitch, not lack of this is less that anyway is a report error, and online debugging code is very troublesome, let a person headache. But Alibaba has made a splash with Arthas, a tool that analyzes and diagnoses Java code online.
❞
What is Arthas?
Arthas is an open source Java online analysis and diagnostics tool for Ali.
What problem does Arthas solve?
In the daily development and online process, we would more or less encounter the following problems, suffering from online debugging, “can only rely on the experience of old birds to hard analysis of bugs, efficiency is not always open to others to answer questions, more or less embarrassed”.
-
From which JAR is this class loaded? Why are all kinds of class-related exceptions reported?
-
Why didn’t the code I changed execute? Did I not commit? Got the branch wrong?
-
If you encounter a problem, you cannot debug it online. Can you only re-publish it by logging?
-
There is a problem with a user’s data processing online, but it cannot be debugged online, and it cannot be reproduced offline!
-
Is there a global view of the health of the system?
-
Is there any way to monitor the real-time health of the JVM?
-
There is an error in the online code and you don’t want to republish it? Can you change the class file and replace it?
Arthas has two installation and startup modes
1. Start the JAR package
wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar --target-ip 0.0. 0. 0
Copy the code
Demo-0.1-snapshot. jar is the test project I started. Arthas automatically checks for all the Java services in the local directory and lists them. We simply type in the sequence number of the project we want to debug. Select 1 to access the arthas interactive platform for the corresponding process
[root@iz2zehzeir87zi8q99krk1z data]# java -jar arthas-boot.jar --target-ip 172.1772.201.
[INFO] arthas-boot version: 3.1. 0
[INFO] Found existing java process, please choose one and hit RETURN.
* [1] :28679 demo0.01.-SNAPSHOT.jar
Copy the code
2, online installation
curl -L https://alibaba.github.io/arthas/install.sh | sh
Copy the code
Running the preceding command will generate the as.sh execution file in the same fileStart the arthas
. /asSh PID # Process ID Specifies the ID of the JAVA process
. /asSh -h #h to obtain more parameter information
Copy the code
3. Remote Connection:
“To use the Arthas service’s Web Console, you must expose the native IP“
java -jar arthas-boot.jar --target-ip 172.1772.201.
java -jar arthas-boot.jar --telnet-port 9999 --http-port - 1
Copy the code
. /as.sh --target-ip 0.0. 0. 0
. /as.sh --telnet-port 9999 --http-port - 1
Copy the code
There are also two ways to access the Arthas Console
“(1) Web Console interface“
“Emphasizes the“: –-target-ip
的ip
Must bearthas
The IP address of the machine exposed,“But if you are using Ali Cloud machine you must start arthas service using private IP, but access must be public IP“
“(2) Telnet“
telnet 10.02.. 5 8563
Copy the code
Visit http://59.110.218.9:8563/, enter the interactive platform
Arthas command is used
1. Dashboard commands
View the real-time data panel of the current system, such as server thread information, memory memory, and GC collection
2. Thread (Thread Monitoring)
$ thread -n 3
"as-command-execute-daemon" Id=57 cpuUsage=72% RUNNABLE
at sun.management.ThreadImpl.dumpThreads0(Native Method)
at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:448)
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 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Number of locked synchronizers = 1
- java.util.concurrent.ThreadPoolExecutor$Worker@a2f70c7
Copy the code
“You can see this thread are synchroned obstruction caused by the key Lock, currently only support to find out the synchronized keyword blocked threads, if is a Java util. Concurrent. The Lock, it is not support.
Number of locked synchronizers = 1
- java.util.concurrent.ThreadPoolExecutor$Worker@a2f70c7
thread -n 3The current busiest N threads
Thread-b, ## Find the thread currently blocking another thread
thread -n 3 -i 1000# Show after a certain interval
Copy the code
## “Find out which thread is currently blocking another thread”
3. JVM (JVM real-time health, memory usage, etc.)
$ jvm
RUNTIME
------------------------------------------------------------------------------------------------------------------------ --------------------------------------------------------------------------------------------------------------------
MACHINE-NAME 28679@iz2zehzeir87zi8q99krk1z
JVM-START-TIME 2019- 03- 28 17:32:16
MANAGEMENT-SPEC-VERSION 1.2
SPEC-NAME Java Virtual Machine Specification
SPEC-VENDOR Oracle Corporation
SPEC-VERSION 1.8
VM-NAME Java HotSpot(TM) 64-Bit Server VM
VM-VENDOR Oracle Corporation
VM-VERSION 25.191-b12
INPUT-ARGUMENTS []
CLASS-PATH demo0.01.-SNAPSHOT.jar
BOOT-CLASS-PATH /usr/local/jdk/jre/lib/resources.jar:/usr/local/jdk/jre/lib/rt.jar:/usr/local/jdk/jre/lib/sunrsasign.jar:/usr/local/jdk/jre/lib/jsse.jar:/usr/local/jdk/jre/lib/jce.jar
:/usr/local/jdk/jre/lib/charsets.jar:/usr/local/jdk/jre/lib/jfr.jar:/usr/local/jdk/jre/classes
LIBRARY-PATH /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
Copy the code
4. Trace (current method internal call path, time of each node on the path)
$trace # class name # method name
Copy the code
For methods that take a long time to execute, the attribute of invoking link time is highlighted for easy troubleshooting
Parameters – j can filter the JDK function trace – j com example. The demo. The controller index2 parameter # can cost according to perform time-consuming ms ms filtering trace – j com example. The demo. The controller Index2 ‘# cost > 10’
5, watch
The current method performs data observation, which can be observed in the following range: return value, throw exception, and input parameter
$trace # class name # method name"{params, target, returnObj, throwExp}"
Copy the code
OGNL expressions {params,target,returnObj, throwExp}
Copy the code
ThrowExp: exception params: input parameter (array), single parameter params [0] returnObj: return value
$ watch com.example.demo.controller index2 "{params,target,returnObj}" -x 5
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt: 1)cost in 81 ms.
ts=2019- 03- 29 14:24:14; [cost=1000.746582ms] result=@ArrayList[
@Object[] [
@String[XIN Zhifu],
].
@controller[
].
@String[index2],
]
Copy the code
6, the stack
The path to which the current method was called, showing which methods the current method was called by
public static String uuidOne() {
return uuidTwo();
}
public static String uuidTwo() {
return UUID.randomUUID().toString().replaceAll("-"."");
}
Copy the code
$ stack com.example.demo.controller uuidTwo
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt: 1)cost in 58 ms.
ts=2019- 03- 29 14:38:19; thread_name=http-nio- 8888.-exec- 5; id=13; is_daemon=true; priority=5; TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@525b461a
@com.example.demo.controller.uuidOne()
at com.example.demo.controller.index2(controller.java:31)
at sun.reflect.GeneratedMethodAccessor36.invoke(null:- 1)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Copy the code
7, monitor command
Monitor class and method calls to monitor the number of calls, times of success, times of failure, average response time, and failure rate
$ monitor -c 4 com.example.demo.controller uuidTwo
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt: 1)cost in 56 ms.
timestamp class method total success fail avg-rt(ms) fail-rate
--------------------------------------------------------------------------------------------------------
The 2019-03-29 14:55:40com.example.demo.controller uuidTwo 7 7 0 0.18 0.00%
Copy the code
8, classloader command
All class loaders in the JVM are counted and displayed as a tree
$classLoader # Tree of each classloader class
name numberOfInstances loadedCountTotal
org.springframework.boot.loader.LaunchedURLClassLoader 1 4463
com.taobao.arthas.agent.ArthasClassloader 2 3631
BootstrapClassLoader 1 2961
java.net.FactoryURLClassLoader 1 835
sun.misc.Launcher$AppClassLoader 1 46
sun.reflect.DelegatingClassLoader 41 41
sun.misc.Launcher$ExtClassLoader 1 25
Affect(row-cnt:7) cost in 7 ms.
$classloader -t # Hierarchy between class loaders
+-BootstrapClassLoader
+-sun.misc.Launcher$ExtClassLoader@1959f618
+-com.taobao.arthas.agent.ArthasClassloader@5fc476c6
+-com.taobao.arthas.agent.ArthasClassloader@5017e14b
+-sun.misc.Launcher$AppClassLoader@5c647e05
+-java.net.FactoryURLClassLoader@4ad317f0
+-org.springframework.boot.loader.LaunchedURLClassLoader@20ad9418
Affect(row-cnt:7) cost in 5 ms
Copy the code
Hot update of online code (dynamic modification of online project code)
Manually throwing exceptions in code,“Modify online code without stopping and resending packets“ The startup of the service was also abnormal as we expected
“Procedure for replacing code:“
1.Jad command
Decompile the files that need to be changed, save them, and the compiler will modify them
$ jad --source--only com.example.demo.DemoApplication > /data/DemoApplication.java
Copy the code
After making the changes, you need to reload the class into the JVM
2,SC command
Find which classLoader loaded the current class
$ sc -d *DemoApplication | grep classLoader
classLoaderHash 20Ad9418 # Class loader number
Copy the code
3,MC command
Recompile the class in memory with the specified ClassLoader
$ mc -c 20ad9418 /data/DemoApplication.java -d /data
Memory compiler output:
/data/com/example/demo/DemoApplication.class
Copy the code
Re-define loads the compiled class into the JVM
The address of the.class file compiled above
$ redefine /data/com/example/demo/DemoApplication.class
redefine success, size: 1
Copy the code
“After the file was replaced, we accessed the program again and found that there was no exception. The class file was replaced successfully“
conclusion
This has enabled us to replace Java code in production with Arthas without stopping and without delivering packages. This article has only covered the surface of arthas’s powerful capabilities, and more detailed articles will follow.
The lazier the more industrious
Arthas’s overall functionality is great, but the way I input from the command line is a pain in my neck, my memory is seriously impaired as I get older, and as a fucking lazy programmer, trying to remember so many commands and parameters is killing me. I decided to do an arthas command visualization platform again because being lazy made me work hard.
“Design intention” : The platform was simply designed to let programmers focus more on troubleshooting problems and less on memorizing boring commands. I am not a person who likes to memorize things by rote. I think I should put more interesting and meaningful things in my mind. Maybe in the eyes of those who are used to using the command line, this function is a bit useless or even a little redundant, but after all, there are more ordinary people like me, who are still trapped in repetitive work every day. If the workload can be reduced, it will be more relaxed.
At present, the platform is still under continuous development. Since the platform is maintained by ourselves, the development schedule is not objective. Usually, we use some fragmented time to develop, after all, we can’t delay our work and lose our job. I’ll keep doing it whether it’s used or not.
“Making address: https://github.com/chengxy-nds/arthas-web.git
“Interested partners can private message me, let’s build this interesting thing together!“
Small benefits:
Pay attention to my public number, reply [666], hundreds of all kinds of technical e-books send, “hush ~”, “free” to everyone, no routine to get