Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.


What is Arthas

Arthas is an open source Java diagnostic tool developed by Alibaba. Arthas can check thread status and JVM information of Java applications and diagnose business problems online, such as checking method call entry and exit parameters, execution process, thrown exceptions, and output method execution time, which greatly improves the efficiency of troubleshooting online problems.

Liverpoolfc.tv: arthas.aliyun.com/zh-cn/

Two, features list

What can Arthas do for you?

Arthas can help you when you are stuck with a problem like:

  1. From which JAR is this class loaded? Why are all kinds of class-related exceptions reported?
  2. Why didn’t the code I changed execute? Did I not commit? Got the branch wrong?
  3. If you encounter a problem, you cannot debug it online. Can you only re-publish it by logging?
  4. There is a problem with a user’s data processing online, but it cannot be debugged online, and it cannot be reproduced offline!
  5. Is there a global view of the health of the system?
  6. Is there any way to monitor the real-time health of the JVM?
  7. How to quickly locate application hot spots, generate flame map?
  8. How do I find an instance of a class directly from the JVM?

Arthas supports JDK 6+, Linux/Mac/Windows, command line interaction, and rich Tab auto-completion to further locate and diagnose problems.

Four, quick installation

1. Prerequisites

[root@c41287379b7c /]# yum install telnet
[root@c41287379b7c /]# yum install unzip
Copy the code

2. One-click installation

Download the Arthas script using the command:

[root@c41287379b7c /]# curl -L https://alibaba.github.io/arthas/install.sh | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   961  100   961    0     0    743      0  0:00:01  0:00:01- : - : -743
downloading... ./as.sh1598.
Arthas install successed.
Copy the code

Download the Arthas JAR package using the command:

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
Copy the code

Arthas provides a JAR package that is essentially a Java application.

Five, quick use

1. Start the script and connect to the process

Quick start with script:

[root@c41287379b7c /]# ./as.sh
Arthas script version: 3.17.
[INFO] JAVA_HOME: /usr/jdk18.. 0 _111
Found existing java process, please choose one and hit RETURN.
* [1] :1 org.apache.catalina.startup.Bootstrap
1      If there are more than one Java process, a list will appear here. Enter the serial number to connect the process.
updating version 3.17.. Download arthas from: https:/ / repo1.maven.org/maven2/com/taobao/arthas/arthas-packaging/3.1.7/arthas-packaging-3.1.7-bin.zip# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #100.0%
Archive:  /tmp/temp_31.7 _1673./arthas-3.17.-bin.zip
   creating: /tmp/temp_31.7 _1673./async-profiler/
  inflating: /tmp/temp_31.7 _1673./arthas-spy.jar
  inflating: /tmp/temp_31.7 _1673./arthas-agent.jar
  inflating: /tmp/temp_31.7 _1673./arthas-client.jar
  inflating: /tmp/temp_31.7 _1673./arthas-boot.jar
  inflating: /tmp/temp_31.7 _1673./arthas-demo.jar
  inflating: /tmp/temp_31.7 _1673./install-local.sh
  inflating: /tmp/temp_31.7 _1673./as.sh
  inflating: /tmp/temp_31.7 _1673./as.bat
  inflating: /tmp/temp_31.7 _1673./as-service.bat
  inflating: /tmp/temp_31.7 _1673./async-profiler/libasyncProfiler-linux-x64.so
  inflating: /tmp/temp_31.7 _1673./async-profiler/libasyncProfiler-mac-x64.so
  inflating: /tmp/temp_31.7 _1673./arthas-core.jar
update completed.
Arthas home: /root/.arthas/lib/3.17./arthas
Calculating attach execution time...
Attaching to 1 using version /root/.arthas/lib/3.17./arthas... Real 0m2.298s user 0m0.302s SYS 0m0.145s Attach success. current timestamp is1583537651
Trying 127.0. 01.. Connected to127.0. 01..
Escape character is '^]'.
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
 /  O  \ |  .--. ' '-.. -'|'--' | / O \ '. -'|. -. | |'--'. '. | | | -. | | - | `. ` - | | | | | | \ \ | | | | | | | | | |. -'| ` --' `--'`--' The '-'   `--'` -'  `--'`--' `--'` -- -- -- -- --'


wiki      https://alibaba.github.io/arthas
tutorials https://alibaba.github.io/arthas/arthas-tutorials
version   3.17.
pid       1
time      2020-03-06 23:34:10

[arthas@1] $Copy the code

2. Start the JAR package and connect to the process

The user executing the program needs to have the same permissions as the target process.

For example, execute as admin:

Sudo su admin && Java -jar arthas-boot.jar or sudo -u admin -eh java-jar arthas-boot.jarCopy the code

If attach does not attach the target process, check the logs under ~/logs/arthas/.

If the download speed is slow, you can use aliyun’s image:

java -jar arthas-boot.jar --repo-mirror aliyun --use-http
Copy the code
java -jar arthas-boot.jar -h Print more parameter information.
Copy the code

Select apply Java process:

$ $ java -jar arthas-boot.jar
* [1]: 35542
  [2]: 71560 math-game.jar
Copy the code

Math-game is the second process, type 2, then enter/Enter. Arthas attaches to the target process and prints a log:

[INFO] Try to attach process 71560
[INFO] Attach process 71560 success.
[INFO] arthas-client connect 127.0.0.1 3658
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
 /  O  \ |  .--. ' '-.. -'|'--' | / O \ '. -'|. -. | |'--'. '. | | | -. | | - | `. ` - | | | | | | \ \ | | | | | | | | | |. -'| ` --' `--'`--' The '-'   `--'` -'  `--'`--' `--'` -- -- -- -- --'Wiki: https://arthas.aliyun.com/doc version: 3.0.5.20181127201536 pid: 71560 time: 19:16:24 $2020-11-28Copy the code

After the Arthas Logo appears, it is ready to use.

Six, use examples

1. Dashboard (real-time data panel of current system)

ID          NAME                              GROUP                   PRIORITY   STATE       %CPU       TIME        INTERRUPTE DAEMON
1572        http-nio-8080-exec-139            main                    5          TIMED_WAITI 18         0:12        false      true
1561        http-nio-8080-exec-138            main                    5          RUNNABLE    17         0:18        false      true
1539        http-nio-8080-exec-131            main                    5          TIMED_WAITI 10         1:17        false      true
1575        http-nio-8080-exec-141            main                    5          TIMED_WAITI 10         0:0         false      true
1573        http-nio-8080-exec-140            main                    5          TIMED_WAITI 9          0:8         false      true
1559        http-nio-8080-exec-136            main                    5          TIMED_WAITI 8          0:29        false      true
1558        grpc-default-executor-1340        main                    5          TIMED_WAITI 4          0:5         false      true
28          grpc-default-worker-ELG-1-4       main                    5          RUNNABLE    4          6:44        false      true
1560        http-nio-8080-exec-137            main                    5          RUNNABLE    4          0:23        false      true
Memory                        used      total     max       usage     GC
heap                          155M      311M      843M      18.47%    gc.ps_scavenge.count               6631
ps_eden_space                 39M       171M      310M      12.72%    gc.ps_scavenge.time(ms)            52792
ps_survivor_space             1M        2M        2M        90.63%    gc.ps_marksweep.count              21
ps_old_gen                    114M      138M      632M      18.10%    gc.ps_marksweep.time(ms)           11572
Runtime
os.name                                                               Linux
os.version                                                            3.10. 0-1062.91..el7.x86_64
java.version                                                          1.8. 0 _111
java.home                                                             /usr/jdk18.. 0 _111/jre
Copy the code

2. Sysprop (View or modify Java properties)

// View all properties
[arthas@1]$ sysprop KEY VALUE ------------------------------------------------------------------------------------------------------------------------ --------------- java.vendor Oracle Corporation sun.java.launcher SUN_STANDARD catalina.base /apache-tomcat-8.59.
 sun.management.compiler    HotSpot 64-Bit Tiered Compilers
......
 java.specification.versio  1.8
 n

[arthas@1] $// View specific properties
[arthas@1]$ sysprop java.rmi.server.hostname
java.rmi.server.hostname=106.5417.234.
[arthas@1]$ sysprop file.encoding
file.encoding=ANSI_X34.-1968
[arthas@1] $// Modify attributes
[arthas@1]$ sysprop user.country
user.country=US
[arthas@1]$ sysprop user.country CN
Successfully changed the system property.
user.country=CN
Copy the code

3. Mbeans (View mbean information in real time)

The -i 1000 parameter is refreshed once every second.

[arthas@1]$ mbean -i 1000 java.lang:type=Threading *Count
 NAME                     VALUE
--------------------------------
 PeakThreadCount          61
 DaemonThreadCount        51
 ThreadCount              59
 TotalStartedThreadCount  1586
Copy the code

4. Thread (View thread)

// View all threads
[arthas@1]$ thread
Threads Total: 59, NEW: 0, RUNNABLE: 24, BLOCKED: 0, WAITING: 9, TIMED_WAITING: 26, TERMINATED: 0
ID      NAME                    GROUP            PRIORIT STATE   %CPU    TIME    INTERRU DAEMON
1572    http-nio-8080-exec-139  main             5       TIMED_W 17      1:32    false   true
1597    http-nio-8080-exec-151  main             5       RUNNABL 15      0:10    false   true
1539    http-nio-8080-exec-131  main             5       TIMED_W 11      2:37    false   true
1591    http-nio-8080-exec-148  main             5       RUNNABL 11      0:23    false   true
1587    http-nio-8080-exec-146  main             5       TIMED_W 9       0:33    false   true
1585    grpc-default-executor-1 main             5       TIMED_W 5       0:9     false   true. Affect(row-cnt:0) cost in 106 ms.
[arthas@1] $Copy the code

Looking at all the threads above, you can see that 1572 consumes 17% of the CPU (this percentage is calculated on a per-CPU basis). So you need to see what this thread is doing.

// View the thread stack information
[arthas@1]$ thread 1572
"http-nio-8080-exec-139" Id=1572 RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:100)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:143)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:173)
    -  locked com.mysql.jdbc.util.ReadAheadInputStream@afb14dd
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2954)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3375)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3365)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3805)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
    -  locked com.mysql.jdbc.JDBC4Connection@21123f41
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
    -  locked com.mysql.jdbc.JDBC4Connection@21123f41
    at com.mysql.jdbc.PreparedStatement.execute$original$vADsw8UZ(PreparedStatement.java:1192)
    -  locked com.mysql.jdbc.JDBC4Connection@21123f41
    at com.mysql.jdbc.PreparedStatement.execute$original$vADsw8UZ$accessor$md9IHdH2(PreparedStatement.java)
 ......
    Number of locked synchronizers = 1
    - java.util.concurrent.ThreadPoolExecutor$Worker@31355af3

Affect(row-cnt:0) cost in 152 ms.
[arthas@1]$
Copy the code

5, thread-n (check the thread stack information of the top CPU)

View the stack of the top 3 threads occupying the CPU at 1 second intervals.

[arthas@1]$ thread -n 3 -i 1000
"http-nio-8080-exec-153" Id=1604 cpuUsage=31% RUNNABLE
    at java.lang.Throwable.fillInStackTrace(Native Method)
    at java.lang.Throwable.fillInStackTrace(Throwable.java:783)
    -  locked java.lang.NoSuchMethodException@41cb2ff9
    at java.lang.Throwable.<init>(Throwable.java:265)
    at java.lang.Exception.<init>(Exception.java:66)... Number of locked synchronizers =1
    - java.util.concurrent.ThreadPoolExecutor$Worker@35ddf68a


"http-nio-8080-exec-150" Id=1595 cpuUsage=27% TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@3fb3dff3
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@3fb3dff3
    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.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
    at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:85)
    at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:31)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)


"http-nio-8080-exec-147" Id=1589 cpuUsage=19% RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:100)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:143)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:173)
    -  locked com.mysql.jdbc.util.ReadAheadInputStream@afb14dd. Number of locked synchronizers =1
    - java.util.concurrent.ThreadPoolExecutor$Worker@5a014dec


Affect(row-cnt:0) cost in 1140 ms.
[arthas@1]$
Copy the code

Jad (Decompiled Code)

[arthas@1]$ jad com.7dgroup.blog.controller.BackBlogController

ClassLoader:
+-ParallelWebappClassLoader
    context: ROOT
    delegate: false
  ----------> Parent Classloader:
  java.net.URLClassLoader@22d7b4f8

  +-java.net.URLClassLoader@22d7b4f8
    +-sun.misc.Launcher$AppClassLoader@18b4aac2
      +-sun.misc.Launcher$ExtClassLoader@5f4fff0

Location:
/apache-tomcat-8.59./webapps/ROOT/WEB-INF/classes/

/* * Decompiled with CFR. * * Could not load the following classes: * com.7dgroup.blog.common.exception.JsonResponseException ...... * /
package com.7dgroup.blog.controller;

import com.7dgroup.blog.common.exception.JsonResponseException;
import com.7dgroup.blog.common.model.Page;
import com.7dgroup.blog.common.model.Response;
import com.7dgroup.blog.controller.BackBlogController;
import com.7dgroup.blog.model.Blog;
import com.7dgroup.blog.model.User;
import com.7dgroup.blog.service.BlogReadService;
import com.7dgroup.blog.service.BlogWriteService;
import com.7dgroup.blog.service.CategoryService;
import com.7dgroup.blog.vo.BlogQuery;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import javax.servlet.http.HttpSession;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ConstructorInter;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value={"/back/blog"})
public class BackBlogController
implements EnhancedInstance.EnhancedInstance {
    @Autowired
    BlogReadService blogReadService;
    @Autowired
    BlogWriteService blogWriteService;
    @Autowired
    CategoryService categoryService;
    private volatile Object _$EnhancedClassField_ws;
    public static volatile /* synthetic */ InstMethodsInter delegate$3vsfol1;
    public static volatile /* synthetic */ InstMethodsInter delegate$s214mp1;
    public static volatile /* synthetic */ ConstructorInter delegate$1726vl1;
    private static final /* synthetic */ Method cachedValue$fhzPhYBQ$0j0d661;
    private static final /* synthetic */ Method cachedValue$fhzPhYBQ$7jqr912;
    private static final /* synthetic */ Method cachedValue$fhzPhYBQ$k1ffbv0;
    private static final /* synthetic */ Method cachedValue$fhzPhYBQ$50tnsu0;
    public static volatile /* synthetic */ InstMethodsInter delegate$l07kai0;
    public static volatile /* synthetic */ InstMethodsInter delegate$b310fa0;
    public static volatile /* synthetic */ ConstructorInter delegate$51jjf90;
    private static final /* synthetic */ Method cachedValue$CYumwYK8$0j0d661;
    private static final /* synthetic */ Method cachedValue$CYumwYK8$7jqr912;
    private static final /* synthetic */ Method cachedValue$CYumwYK8$k1ffbv0;
    private static final /* synthetic */ Method cachedValue$CYumwYK8$50tnsu0;

    public BackBlogController(a) {
        this(null);
        delegate$51jjf90.intercept(this.new Object[0]);
    }

    private /* synthetic */ BackBlogController(auxiliary.xIr7AqvV xIr7AqvV2) {
    }

    @RequestMapping(value={""})
    public String page(Model model, Page<Blog> page, BlogQuery blogQuery, HttpSession httpSession) {
        return (String)delegate$b310fa0.intercept(this.newObject[]{model, page, blogQuery, httpSession}, (Callable<? >)new auxiliary.ADTaVnew(this, model, page, blogQuery, httpSession), cachedValue$CYumwYK8$7jqr912); }...final /* synthetic */ Object delete$original$PYp487Vn$accessor$CYumwYK8(Long l) {
        return this.delete$original$PYp487Vn(l);
    }
}

Affect(row-cnt:9) cost in 1594 ms.
[arthas@1] $Copy the code

7, sc (check the loaded class)

[arthas@1]$ sc -d com.jt.blog.controller.BackBlogController
 class-info        com.jt.blog.controller.BackBlogController
 code-source       /apache-tomcat- 8.5.9 /webapps/ROOT/WEB-INF/classes/
 name              com.jt.blog.controller.BackBlogController
 isInterface       false
 isAnnotation      false
 isEnum            false
 isAnonymousClass  false
 isArray           false
 isLocalClass      false
 isMemberClass     false
 isPrimitive       false
 isSynthetic       false
 simple-name       BackBlogController
 modifier          public.classLoaderHash   15101d33

Affect(row-cnt: 2)cost in 48 ms.arthas@ $1]Copy the code

8. Sm (List the methods used to load a class)

[arthas@1]$ sm com.jt.blog.controller.BackBlogController
com.jt.blog.controller.BackBlogController$$EnhancerBySpringCGLIB$$d6e1bd41 <init>()V
com.jt.blog.controller.BackBlogController$$EnhancerBySpringCGLIB$$d6e1bd41 page(Lorg/springframework/ui/Model; Lcom/jt/blog/common/model/Page; Lcom/jt/blog/vo/BlogQuery; Ljavax/servlet/http/HttpSession;)Ljava/lang/String; . Affect(row-cnt:73) cost in 17 ms.
[arthas@1] $Copy the code

9. Trace (Elapsed time of tracing method)

We can use the trace command to find the most time-consuming method by knowing the package name, class name, and method name.

[arthas@1]$ trace com.jt.blog.controller.BackBlogController$$EnhancerBySpringCGLIB$$d6e1bd41 page
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt: 1)cost in 235 ms. ` -ts=2020-03-07 00:40:01; thread_name=http-nio-8080-exec-167; id=662; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@15101d33 `---[91.777786ms] com.jt.blog.controller.BackBlogController$$EnhancerBySpringCGLIB$$d6e1bd41:page()
        `---[91.101545ms] org.springframework.cglib.proxy.MethodInterceptor:intercept() #0

`---ts=2020-03-07 00:40:02; thread_name=http-nio-8080-exec-166; id=661; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@15101d33 `---[58.901494ms] com.jt.blog.controller.BackBlogController$$EnhancerBySpringCGLIB$$d6e1bd41:page()
        `---[58.727281ms] org.springframework.cglib.proxy.MethodInterceptor:intercept() #0

`---ts=2020-03-07 00:40:02; thread_name=http-nio-8080-exec-150; id=63b; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@15101d33 `---[93.064632ms] com.jt.blog.controller.BackBlogController$$EnhancerBySpringCGLIB$$d6e1bd41:page()
        `---[92.902346ms] org.springframework.cglib.proxy.MethodInterceptor:intercept() #0. [arthas@1]$ trace tk.mybatis.mapper.common.Mapper insert
Press Q or Ctrl+C to abort.
Affect(class-cnt:5 , method-cnt5) :cost in 538 ms. ` -ts=2020-03-07 00:59:22; thread_name=http-nio-8080-exec-172; id=671; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@15101d33 `---[2.938966ms] com.sun.proxy.$Proxy90:insert()

`---ts=2020-03-07 00:59:22; thread_name=http-nio-8080-exec-172; id=671; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@15101d33 `---[0.895433ms] com.sun.proxy.$Proxy93:insert()

`---ts=2020-03-07 00:59:24; thread_name=http-nio-8080-exec-150; id=63b; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@15101d33 `---[2.156481ms] com.sun.proxy.$Proxy90:insert()
Copy the code
[arthas@1]$ trace com.jt.blog.service.BlogReadServiceImpl page
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt: 1)cost in 371 ms. ` -ts=2020-03-07 01:04:44; thread_name=http-nio-8080-exec-6; id=32; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@3d0c8d44 `---[75.94035ms] com.jt.blog.service.BlogReadServiceImpl:page()
        +---[0.034707ms] com.jt.blog.common.model.Response:<init>() #34+ -- -- -0.019337ms] com.jt.blog.common.model.Page:getPageNo() #36+ -- -- -0.01106ms] com.jt.blog.common.model.Page:getPageSize() #36+ -- -- -4.590002ms] com.github.pagehelper.PageHelper:startPage() #36+ -- -- -0.542359ms] tk.mybatis.mapper.entity.Example:<init>() #37+ -- -- -0.070315ms] tk.mybatis.mapper.entity.Example:createCriteria() #38+ -- -- -0.037231ms] com.jt.blog.vo.BlogQuery:getCategoryId() #40+ -- -- -0.007289ms] com.jt.blog.vo.BlogQuery:getBeginTime() #43+ -- -- -0.007167ms] com.jt.blog.vo.BlogQuery:getPersonal() #46+ -- -- -0.006318ms] com.jt.blog.vo.BlogQuery:getPersonal() #47+ -- -- -0.009675ms] tk.mybatis.mapper.entity.Example$Criteria:andEqualTo() #47+ -- -- -30.90447ms] tk.mybatis.mapper.common.Mapper:selectByExample() #50+ -- -- -36.179664ms] com.jt.blog.service.BlogReadServiceImpl:wrapBlogStatistics() #51 [throws Exception]
        +---[0.785948ms] com.google.common.base.Throwables:getStackTraceAsString() #58+ -- -- -0.522234ms] org.slf4j.Logger:error() #58
        `---[0.030388ms] com.jt.blog.common.model.Response:setError() #59

`---ts=2020-03-07 01:04:44; thread_name=http-nio-8080-exec-10; id=3c; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@3d0c8d44 `---[94.699363ms] com.jt.blog.service.BlogReadServiceImpl:page()
        +---[0.009802ms] com.jt.blog.common.model.Response:<init>() #34+ -- -- -0.007825ms] com.jt.blog.common.model.Page:getPageNo() #36.Copy the code

We can see that the total time of page method is 75.94035 ms:

  • SelectByExample call time 30.90447 ms;
  • It took 36.179664 ms to call wrapBlogStatistics;
  • StartPage Invocation takes 4.590002 ms.

The selectByExample and wrapBlogStatistics methods take a long time, and when you can pinpoint the method-level consumption time, you can find the reason for the slowness.

10. Stack (View the call stack of a method)

[arthas@1]$ stack tk.mybatis.mapper.common.Mapper insert
Press Q or Ctrl+C to abort.
Affect(class-cnt:5 , method-cnt5) :cost in 561 ms.
ts=2020-03-07 01:00:51; thread_name=http-nio-8080-exec-171; id=66f; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@15101d33@com.jt.blog.service.BlogWriteServiceImpl.create()
        at sun.reflect.GeneratedMethodAccessor255.invoke(null: -1)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)... ts=2020-03-07 01:00:51; thread_name=http-nio-8080-exec-171; id=66f; is_daemon=true; priority=5; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@15101d33@com.jt.blog.service.BlogWriteServiceImpl.create()
        at sun.reflect.GeneratedMethodAccessor255.invoke(null: -1)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)... [arthas@1] $Copy the code

11. Classloader (view the classLoader inheritance tree, urls, classloading information)

[arthas@1]$ classloader
 name                                                                 numberOfInstances  loadedCountTotal
 org.apache.catalina.loader.ParallelWebappClassLoader                 2                  6680
 BootstrapClassLoader                                                 1                  3836
 sun.misc.Launcher$AppClassLoader                                     1                  3029
 com.taobao.arthas.agent.ArthasClassloader                            1                  1194
 java.net.URLClassLoader                                              1                  860
 org.apache.skywalking.apm.agent.core.plugin.loader.AgentClassLoader  3                  306
 sun.reflect.DelegatingClassLoader                                    289                289
 sun.misc.Launcher$ExtClassLoader                                     1                  13
 javax.management.remote.rmi.NoCallStackClassLoader                   2                  2
Affect(row-cnt:9) cost in 36 ms.
[arthas@1] $Copy the code

12. Monitor (Monitoring method)

[arthas@1]$ monitor -h
 USAGE:
   monitor [-c <value>] [-h] [-n <value>] [-E <value>] class-pattern method-pattern

 SUMMARY:
   Monitor method execution statistics.e.g. total/success/failure count.average rt.fail rate.etc.

 Examples:
   monitor org.apache.commons.lang.StringUtils isBlank
   monitor org.apache.commons.lang.StringUtils isBlank -c 5
   monitor -E org\.apache\.commons\.lang\.StringUtils isBlank

 WIKI:
   https: / /alibaba.github.io/arthas/monitor

 OPTIONS:
 -c, -cycle <value>                          The monitor interval (in seconds), 60 seconds by default
 -h, -help                                   this help
 -n, -limits <value>                         Threshold of execution times
 -E, -regex <value>                          Enable regular expression to match (wildcard matching by default)
 <class-pattern>                              Path and classname of Pattern Matching
 <method-pattern>                             Method of Pattern Matching

[arthas@ $1]Copy the code

Example:

[arthas@1]$ monitor tk.mybatis.mapper.common.Mapper insert
Press Q or Ctrl+C to abort.
Affect(class-cnt:5 , method-cnt5) :cost in 411 ms.
 timestamp            class                   method  total  success  fail  avg-rt(ms)  fail-rat
                                                                                        e-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the 2020-03-07 01:11:38com.sun.proxy. $Proxy93  insert  197    197      0     1.67        0.00%
 2020-03-07 01:11:38  com.sun.proxy. $Proxy90  insert  197    197      0     3.39        0.00%
Copy the code

Seven,

In this article, I mainly introduced what Arthas is, why it is used, and demonstrated how Arthas commands are used. Examples are typical ways to troubleshoot online problems and demonstrate the power and convenience of Arthas.