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-ipipMust bearthasThe 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 commandDecompile 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
Insert a picture description here

After making the changes, you need to reload the class into the JVM

2,SC commandFind which classLoader loaded the current class

$ sc -d *DemoApplication | grep classLoader



 classLoaderHash   20Ad9418 # Class loader number

Copy the code

3,MC commandRecompile 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, size1

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