Arthas official community is holding an essay contest for prizesClick on the submit】

The author | Yang Zhen building, pen name three knife knife, is a leading Internet WangMa farmers, visiting a year to stay in the United States, mainly focus on the backend development, data security, the crawler, Internet of things, the calculation of edge direction.

preface

As you excitedly start running your Java project, have you encountered any of the following problems:

  • The program is running stably, but the implemented function point is not responding.
  • A new version released to fix a Bug, only to find that the Bug is still there, but can’t figure out what the problem is?
  • When I think of a possible problem, I find that there is no log there, so I can’t see the problem in the run, so I have to add log output and repackage — deploy — live
  • The program is working fine, but why is the response time so slow? Where is the problem?
  • The program is stable and perfectly functional, but after a few days or weeks of running, the response is slow. Is there a memory leak?

In the old days, when you had these problems, the answer was mostly to change the code and go back online. But in large companies, the process of going live can be tedious, and it can be very frustrating to re-release a version just to add one more log line.

Now we have a more elegant way to debug online – Arthas from Alibaba open source.

Below is the Arthas documentation’s description of why it should be used, which I have condensed:

Well, the preface has exceeded the word count, ha ha, in this article, you can understand:

  • Arthas Use example: Help you get started quickly and save your inefficient debugs
  • Use Arthas for specific problems: Look at how much time Arthas has saved for me
  • Similar tools: See if there are any other tools available for online Debug
  • Principle of shallow talk: mo in floating sand build high castle! You need to get a sense of how Arthas works

Trust me, Arhas is a great productivity tool for developers of all stages, especially for beginners like me. You shouldn’t have the idea that something is for advanced programmers to use, just go ahead and use it!

Online Debug artifact Arthas

Arthas example

Please refer to the detailed document of command: alibaba. Making. IO/arthas/comm…

Quick start

To start it up quickly, you only need two lines of command:

wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar
Copy the code

Then, in the process that appears on the screen, select your program number, such as 1

This brings you to arthas’s console.

The basic use

Arthas has the following functions:

1. The first is what I consider the “God’s View” command: Dashboard

In the real-time data panel of the current system, press CTRL + C to exit. When running ali-Tomcat, real-time information about the current Tomcat is displayed, such as QPS for HTTP requests, RT, number of errors, thread pool information, and so on.

Through this, you can have a visual data monitoring of the entire application process.

2. Instructions related to class loading problems

SC: View information about classes loaded by the JVM

From SC we can see the details of our class, including which JAR it was read from, whether it was an interface/enumeration class, and even which class loader it was loaded from.

The code in the figure above:

[arthas@37]$ sc -d *MathGame
 class-info        demo.MathGame
 code-source       /home/scrapbook/tutorial/arthas-demo.jar
 name              demo.MathGame
 isInterface       false
 isAnnotation      false
 isEnum            false
 isAnonymousClass  false
 isArray           false
 isLocalClass      false
 isMemberClass     false
 isPrimitive       false
 isSynthetic       false
 simple-name       MathGame
 modifier          public
 annotation
 interfaces
 super-class       +-java.lang.Object
 class-loader      +-sun.misc.Launcher$AppClassLoader@70dea4e
                     +-sun.misc.Launcher$ExtClassLoader@69260973
 classLoaderHash   70dea4e
Copy the code

SC can also look at loaded classes to help you see if there are any included classes, especially in Spring, to determine if your dependencies are coming in correctly.

The code in the figure above:

Check the JVM for loaded classes
[arthas@37]$ sc javax.servlet.Filter
com.example.demo.arthas.AdminFilterConfig$AdminFilter
javax.servlet.Filter
org.apache.tomcat.websocket.server.WsFilter
org.springframework.boot.web.filter.OrderedCharacterEncodingFilter
org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter
org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter
org.springframework.boot.web.filter.OrderedRequestContextFilter
org.springframework.web.filter.CharacterEncodingFilter
org.springframework.web.filter.GenericFilterBean
org.springframework.web.filter.HiddenHttpMethodFilter
org.springframework.web.filter.HttpPutFormContentFilter
org.springframework.web.filter.OncePerRequestFilter
org.springframework.web.filter.RequestContextFilter
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter
Affect(row-cnt:14) cost in 11 ms.
 
Check the method information of the loaded class[arthas@37]$ sm java.math.RoundingMode java.math.RoundingMode <init>(Ljava/lang/String; II)V java.math.RoundingMode values()[Ljava/math/RoundingMode; java.math.RoundingMode valueOf(I)Ljava/math/RoundingMode;  java.math.RoundingMode valueOf(Ljava/lang/String;)Ljava/math/RoundingMode; Affect(row-cnt:4) costin 6 ms.
Copy the code

Jad: decompile a class or a method of a class.

The code in the figure above:

# decompile displays only the source code
jad --source-only com.Arthas
Decompile a method of a class
jad --source-only com.Arthas mysql
[arthas@37]$ jad demo.MathGame
ClassLoader:
+-sun.misc.Launcher$AppClassLoader@70dea4e
  +-sun.misc.Launcher$ExtClassLoader@69260973
Location:
/home/scrapbook/tutorial/arthas-demo.jar
/*
 * Decompiled with CFR.
 */
package demo;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MathGame {
    private static Random random = new Random();
    public int illegalArgumentCount = 0;
    public List<Integer> primeFactors(int number) {
        if (number < 2) {
            ++this.illegalArgumentCount;
            throw new IllegalArgumentException("number is: " + number + ", need >= 2");
        }
        ArrayList<Integer> result = new ArrayList<Integer>();
        int i = 2;
        while (i <= number) {
            if (number % i == 0) {
                result.add(i);
                number /= i;
                i = 2;
                continue;
            }
            ++i;
        }
        return result;
    }
    public static void main(String[] args) throws InterruptedException {
        MathGame game = new MathGame();
        do {
            game.run();
            TimeUnit.SECONDS.sleep(1L);
        } while (true);
    }
    public void run() throws InterruptedException {
        try {
            int number = random.nextInt() / 10000;
            List<Integer> primeFactors = this.primeFactors(number);
            MathGame.print(number, primeFactors);
        }
        catch (Exception e) {
            System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage());
        }
    }
    public static void print(int number, List<Integer> primeFactors) {
        StringBuffer sb = new StringBuffer(number + "=");
        for (int factor : primeFactors) {
            sb.append(factor).append(The '*');
        }
        if (sb.charAt(sb.length() - 1) == The '*') {
            sb.deleteCharAt(sb.length() - 1);
        }
        System.out.println(sb);
    }
}
Affect(row-cnt:1) cost in 760 ms.
Copy the code

3. Methods Run related instructions

Watch: Data observations performed by the method

You can monitor a class with the Watch command, and then run your functionality and reproduce the scene, arthas will give you specific exit and entry parameters to help you troubleshoot.

Trace: Outputs the method invocation path and time

This instruction is very useful for optimizing code, you can see the specific execution time of each method, if the for loop is repeated, you can also see the maximum time, minimum time, and average time in n loops, perfect!

Tt: Officially called time Tunnel

This is the most common instruction I use for debugging. After you enable tt for a method, it records every call (you need to set the maximum number of times to monitor), and then you can view the call at any time, including the outgoing parameter, the incoming parameter, the running time, whether the exception, etc. Very powerful.

4. Thread debugging related instructions

Thread related commands:

Thread-n: lists the threads with Top N CPU usage.

Thread-b: checks the blocked threads

Our code is sometimes poorly designed, resulting in deadlocks that block the execution of the entire thread. Using this command, you can easily find the problem thread and the execution statement of the problem.

5. Powerful OGNL expressions

As we all know, expressions are generally the strongest instructions in a debugging tool, haha.

You can do a lot of things with the OGNL expression language in Arthas, such as executing a method, getting information, and even making changes.

[arthas@19856]$ ognl '@com.Arthas@hashSet'
@HashSet[
    @String[count1],
    @String[count2],
    @String[count29],
    @String[count28],
    @String[count0],
    @String[count27],
    @String[count5],
    @String[count26],
    @String[count6],
    @String[count25],
    @String[count3],
    @String[count24],
    
[arthas@19856]$ ognl  '@[email protected]("test")'
@Boolean[true]
[arthas@19856]$
# View the added characters
[arthas@19856]$ ognl  '@com.Arthas@hashSet' | grep test
    @String[test],
[arthas@19856]$
Copy the code

You can even change the log output level dynamically.

$ ognl '@[email protected]'
@PrivateConfig[
    loggerConfig=@LoggerConfig[root],
    loggerConfigLevel=@Level[INFO],
    intLevel=@Integer[400],
]
$ ognl '@[email protected](@org.apache.logging.log4j.Level@ERROR)'
null
$ ognl '@[email protected]'
@PrivateConfig[
    loggerConfig=@LoggerConfig[root],
    loggerConfigLevel=@Level[ERROR],
    intLevel=@Integer[200],
  
]
Copy the code

Use Arthas to solve specific problems

1. Abnormal response time

A optimization problems in the work, an export form functions of the system, the response time for 2 minutes, although for internal use, but also can’t so exaggerated, with trace tracking method, discovery is one of the mobile phone number encryption function very big time, thousands of mobile phone number, after decryption encryption operation, This resulted in a two-minute return time.

2. The server returns 500 due to a function Bug

First, we checked the error reporting method through trace. Then, we checked the TT method, and found that after the entry, we actually went to the wrong method (because of polymorphism), and went to the method that returned null, which led to the NPE null pointer error.

supplement

Arthas also supports Web Console, see: alibaba. Making. IO/Arthas/Web -…

Similar tools

BTrace is a very old tool, and Arthas is very similar in concept when I look at it. I believe Arthas also used BTrace as a learning example to develop Arthas. Detailed advantages and disadvantages:

Other similar tools, as well as jVM-Sandbox, are available for those interested.

The principle of introduction

Divided into three parts:

  • Start the
  • Arthas server side code analysis
  • Arthas client code analysis

Start the

Using the cli ali open source components, the parameters for the analytic: com. Taobao. Arthas. Boot. The Bootstrap

Without a PID in the passed argument, the local JPS command is invoked to list the Java processes.

Arthas directory will be created under the user directory, arthas-core and arthas-Agent lib files will be downloaded, and the client and server will be started.

Start the character client by reflection.

Server – Preparations

Look at server startup command can know from arthas – core. The jar to start, arthas – the core of pom. XML file specifies the mainClass inside for the com. Taobao. Arthas. Core. Arthas, Causes the program to start running from the main method of the class.

  • First parsing the ginseng, generate com. Taobao. Arthas. Core. Config. The Configure class, contains the relevant configuration information;
  • LoadAgent: VirtualMachine. LoadAgent: VirtualMachine. LoadAgent: VirtualMachine. The second argument loads the arthas-agent.jar package by passing arguments to the agentMain () method in the jar package (in this case the agent-core.jar package path and config serialized string);
  • Run arthas – agent. The jar package, specify the agent – Class for the com. Taobao. Arthas. Agent. AgentBootstrap.

The code in the figure above:

public class Arthas { private Arthas(String[] args) throws Exception { attachAgent(parse(args)); } private Configure parse(String[] args) {// Omit non-critical code, parse startup parameters as configuration, and populate the Configure objectreturnconfigure; } private void attachAgent(Configure Configure) throws Exception {// Omit non-critical code, VirtualMachine = virtualMachine. Attach ("" + configure.getJavaPid());
          virtualMachine.loadAgent(configure.getArthasAgent(),
                            configure.getArthasCore() + ";"+ configure.toString()); } public static void main(String[] args) { new Arthas(args); }}Copy the code

Server – Listens for client requests

  • If the exit, logout, quit, jobs, fg, bg, kill and other direct execution;
  • For other commands, create a Job and run it.
  • When creating a Job, the system finds the corresponding Command based on the Command transmitted by the client and packages it as Process, which is then packaged as Job.
  • When running a Job, Process is called in reverse order to find the corresponding Command, and the Command Process is called to Process the request.

Server side — Command handles the flow

  1. No bytecode-enhanced commands are required

JVMS use the management interface provided by java.lang.management to view specific runtime data. I’m not going to introduce it.

  1. Commands that require bytecode enhancement

The bytecode increment commands inherit from the EnhancerCommand class, enhanced by calling the Enhance method inside the Process method. Call the Enhancer class Enhance method, which internally calls the Inst. addTransformer method to add a custom ClassFileTransformer, and here is the Enhancer class.

The Enhancer class uses AdviceWeaver(inheritance ClassVisitor) to modify the bytecode of the class. Overrides the visitMethod method to modify the method specified by the class. VisitMethod uses AdviceAdapter (inherits the MethodVisitor class), onMethodEnter, onMethodExit, Weave the Spy class’s corresponding methods (ON_BEFORE_METHOD, ON_RETURN_METHOD, ON_THROWS_METHOD, etc.) into the target class’s corresponding methods.

As you can see from the Spy initialization, these methods refer to methodOnBegin, methodOnReturnEnd, and so on of the AdviceWeaver class. In these methods, the corresponding AdviceListener is searched according to adviceId, and the corresponding methods of AdviceListener are called, such as before,afterReturning, afterThrowing.

The client

The client code in arthas – client module, and entrance class is com. Taobao. Arthas. Client. TelnetConsole.

The apache Commons-net JAR is mainly used for Telnet connections. The key code is as follows:

  1. Construct the TelnetClient object and initialize it
  2. Construct the ConsoleReader object and initialize it
  3. Call ioutil.readwrite (telnet.getinputStream (), telnet.getOutputStream(), system.in, consoleReader. GetOutput ()) to process each stream, There are four streams:
    • telnet.getInputStream()
    • telnet.getOutputStream()
    • System.in
    • consoleReader.getOutput()

When requested: read from local system.in and send to telnet.getOutputStream(), that is, to the remote server. Response time: Read the response sent from the remote server from telnet.getinputStream () and pass it to consolereader.getOutput (), that is, output at the local console.

On the source code, there are still a lot of things to eat, I did not digest well, you can continue to read the details.

conclusion

Arthas is an online Debug artifact that Haku can easily use.

One click to install and start Arthas

  • Method 1: Implement Arthas one-click remote diagnosis using Cloud Toolkit

Cloud Toolkit is a free local IDE plug-in released by AliYun to help developers develop, test, diagnose and deploy applications more efficiently. Plugins enable one-click deployment of native applications to any server, even the cloud (ECS, EDAS, ACK, ACR, applets, etc.); There are also built-in Arthas diagnostics, Dubbo tools, Terminal terminals, file uploads, function calculations, and MySQL executators. Not only the mainstream version of IntelliJ IDEA, but also Eclipse, Pycharm, Maven and others.

It is recommended to download Cloud Toolkit using the IDEA plugin to use Arthas: t.tb.cn/2A5CbHWveOX…

  • Method 2: Download directly

Address: github.com/alibaba/art… .

reference

Open source: github.com/alibaba/art… Official documentation: Baba.github. IO /arthas

Arthas’s essay campaign is in full swing

Arthas is officially holding an essay call if you have:

  • Problems identified using Arthas
  • Source code interpretation of Arthas
  • Advise Arthas
  • No limit, other Arthas related content

Welcome to participate in the essay activity, there are prizes to win oh ~ click to submit

“Alibaba Cloud originator focuses on micro-service, Serverless, container, Service Mesh and other technical fields, focuses on the trend of cloud native popular technology, large-scale implementation of cloud native practice, and becomes the public account that most understands cloud native developers.”