当前位置 : 首页 » 文章分类 :  开发  »  Arthas

Arthas

Arthas 使用笔记

alibaba / arthas
https://github.com/alibaba/arthas


命令

https://arthas.aliyun.com/doc/commands.html


trace 方法调用路径及各节点耗时

https://arthas.aliyun.com/doc/trace.html

trace 完全限定类名 方法名 跟踪方法内部调用路径,并输出方法路径上的每个节点上耗时
trace 完全限定类名 方法名 '#cost>5' 只展示耗时大于5毫秒的,方便排查慢方法

[arthas@86]$ trace demo.MathGame run
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 150 ms, listenerId: 1
`---ts=2022-06-28 11:34:09;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44
    `---[1.01795ms] demo.MathGame:run()
        +---[30.04% 0.305773ms ] demo.MathGame:primeFactors() #24
        `---[20.31% 0.206752ms ] demo.MathGame:print() #25

stack 方法被调用路径

https://arthas.aliyun.com/doc/stack.html

stack 完全限定类名 方法名 输出当前方法被调用的调用路径
stack 完全限定类名 方法名 '#cost>5' 只展示耗时大于5毫秒的,方便排查慢方法

[arthas@54842]$ stack demo.MathGame primeFactors
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 69 ms, listenerId: 16
ts=2022-06-28 21:18:18;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@70dea4e
    @demo.MathGame.primeFactors()
        at demo.MathGame.run(MathGame.java:24)
        at demo.MathGame.main(MathGame.java:16)

monitor 方法平响/成功率统计

https://arthas.aliyun.com/doc/monitor.html

monitor 完全限定类名 方法名 对方法调用进行监控,可看到平响、成功率
-c 5 以5秒为统计周期,默认是120秒

[arthas@38573]$ monitor -c 5 demo.MathGame primeFactors
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 26 ms, listenerId: 3
 timestamp            class          method        total   success   fail   avg-rt(ms)   fail-rate
--------------------------------------------------------------------------------------------------
 2022-06-28 20:15:48  demo.MathGame  primeFactors  5       2         3      0.11         60%                                                                                

thread 查看cpu占用高的线程


watch 看方法入参和返回值

https://arthas.aliyun.com/doc/watch.html

watch 完全限定类名 方法名 查看方法执行的入参、异常、返回值
-x 指定输出结果的属性遍历深度,默认为 1,最大值是4,-x 2 才能看到调用的入参和返回值

watch 结果中的 result 是观察表达式,默认值是 {params, target, returnObj} 即参数、this对象和返回值

watch 命令的结果里,会打印出 location 信息。location 有三种可能值:

  • AtEnter 函数入口
  • AtExit 函数正常return
  • AtExceptionExit 函数抛出异常

示例1、方法执行异常

[arthas@54842]$ watch demo.MathGame primeFactors -x 2
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 32 ms, listenerId: 5
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2022-06-28 20:49:54; [cost=0.356875ms] result=@ArrayList[
    @Object[][
        @Integer[-61463],
    ],
    @MathGame[
        random=@Random[java.util.Random@254989ff],
        illegalArgumentCount=@Integer[176],
    ],
    null,
]

location=AtExceptionExit 表示方法执行异常,所以 returnObj 是 null

示例2、方法正常返回

[arthas@54842]$ watch demo.MathGame primeFactors -x 2
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 30 ms, listenerId: 8
method=demo.MathGame.primeFactors location=AtExit
ts=2022-06-28 20:54:25; [cost=1.681583ms] result=@ArrayList[
    @Object[][
        @Integer[1],
    ],
    @MathGame[
        random=@Random[java.util.Random@254989ff],
        illegalArgumentCount=@Integer[309],
    ],
    @ArrayList[
        @Integer[7],
        @Integer[19],
        @Integer[139],
    ],
]

location=AtExit 表示方法正常返回
result 中第一个是入参,最后的是结果


sc 查看类信息

https://arthas.aliyun.com/doc/sc.html

sc 完全限定类名 Search-Class,查看 JVM 已加载的类信息
-d 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。
如果一个类被多个 ClassLoader 所加载,-d 结果中会出现多次,所以可以通过 sc -d 看到是否一个类被多个类加载器加载

[arthas@86]$ sc -d demo.MathGame
 class-info        demo.MathGame                                                                    
 code-source       /root/math-game.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      +-jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44                        
                     +-jdk.internal.loader.ClassLoaders$PlatformClassLoader@1152c911                
 classLoaderHash   c387f44                                                                          

Affect(row-cnt:1) cost in 22 ms.

sm 查看类的方法信息

https://arthas.aliyun.com/doc/sm.html

sm 完全限定类名 Search-Method,查看已加载的类的方法信息
-d 展示每个方法的详细信息

[arthas@86]$ sm demo.MathGame
demo.MathGame <init>()V
demo.MathGame main([Ljava/lang/String;)V
demo.MathGame run()V
demo.MathGame print(ILjava/util/List;)V
demo.MathGame primeFactors(I)Ljava/util/List;
Affect(row-cnt:5) cost in 7 ms.

ognl 执行ognl表达式

https://arthas.aliyun.com/doc/ognl.html

ognl 'ognl表达式' 执行 ognl 表达式

OGNL(Object-Graph Navigation Language) 是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。
https://commons.apache.org/proper/commons-ognl/index.html

1、ognl 调用静态方法

[arthas@90922]$ ognl '@java.lang.System@currentTimeMillis()'
@Long[1656678870758]
[arthas@90922]$ ognl '@java.lang.System@out.println("hell")'
null

2、执行多行表达式,赋值给临时变量,返回一个List

[arthas@90922]$ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
@ArrayList[
    @String[/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre],
    @String[OpenJDK Runtime Environment],
]

jad 反编译类/方法

https://arthas.aliyun.com/doc/jad.html

jad 完全限定类名 反编译指定的类
jad 完全限定类名 方法名 反编译指定的方法

默认情况下,反编译结果里会带有ClassLoader信息,通过 –source-only 选项,可以只打印源代码。

[arthas@54842]$ jad demo.MathGame

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@70dea4e
  +-sun.misc.Launcher$ExtClassLoader@1b6d3586

Location:
/Users/masi/.arthas/lib/3.6.2/arthas/math-game.jar

       /*
        * Decompiled with CFR.
        */
       package demo;

       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();
           private int illegalArgumentCount = 0;

           public static void main(String[] args) throws InterruptedException {
               MathGame game = new MathGame();
               while (true) {
/*16*/             game.run();
/*17*/             TimeUnit.SECONDS.sleep(1L);
               }
           }

           public void run() throws InterruptedException {
               try {
/*23*/             int number = random.nextInt() / 10000;
/*24*/             List<Integer> primeFactors = this.primeFactors(number);
/*25*/             MathGame.print(number, primeFactors);
               }
               catch (Exception e) {
/*28*/             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 + "=");
/*34*/         for (int factor : primeFactors) {
/*35*/             sb.append(factor).append('*');
               }
/*37*/         if (sb.charAt(sb.length() - 1) == '*') {
/*38*/             sb.deleteCharAt(sb.length() - 1);
               }
/*40*/         System.out.println(sb);
           }

           public List<Integer> primeFactors(int number) {
/*44*/         if (number < 2) {
/*45*/             ++this.illegalArgumentCount;
                   throw new IllegalArgumentException("number is: " + number + ", need >= 2");
               }
               ArrayList<Integer> result = new ArrayList<Integer>();
/*50*/         int i = 2;
/*51*/         while (i <= number) {
/*52*/             if (number % i == 0) {
/*53*/                 result.add(i);
/*54*/                 number /= i;
/*55*/                 i = 2;
                       continue;
                   }
/*57*/             ++i;
               }
/*61*/         return result;
           }
       }

Affect(row-cnt:1) cost in 451 ms.

安装 Arthas

https://arthas.aliyun.com/doc/install-detail.html

在线安装 Arthas

wget https://arthas.aliyun.com/arthas-boot.jar 下载只有 100 多 kb 的 arthas-boot.jar
java -jar arthas-boot.jar 启动后会自动检测 jvm 进程,输入序号选择一个 jvm 进程,然后开始自动下载需要的其他 jar 包,完成后会自动 attach 到进程上即可开始使用。

java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.6.2
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 74225
  [2]: 70338
  [3]: 59427 org.jetbrains.idea.maven.server.RemoteMavenServer36
  [4]: 51391 com.intellij.database.remote.RemoteJdbcServer
1
[INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/3.6.2?mirror=aliyun
[INFO] File size: 12.88 MB, downloaded size: 2.00 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 3.86 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 5.50 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 6.81 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 8.48 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 10.27 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 12.11 MB, downloading ...
[INFO] Download arthas success.
[INFO] arthas home: /Users/masi/.arthas/lib/3.6.2/arthas
[INFO] Try to attach process 74225
[WARN] Current VM java version: 1.8 do not match target VM java version: 11, attach may fail.
[WARN] Target VM JAVA_HOME is /Applications/DataGrip.app/Contents/jbr/Contents/Home, arthas-boot JAVA_HOME is /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre, try to set the same JAVA_HOME.
java.io.IOException: Non-numeric value found - int expected
    at sun.tools.attach.HotSpotVirtualMachine.readInt(HotSpotVirtualMachine.java:299)
    at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:63)
    at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:79)
    at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:103)
    at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:122)
    at com.taobao.arthas.core.Arthas.<init>(Arthas.java:27)
    at com.taobao.arthas.core.Arthas.main(Arthas.java:151)
[WARN] It seems to use the lower version of JDK to attach the higher version of JDK.
[WARN] This error message can be ignored, the attach may have been successful, and it will still try to connect.
[INFO] Attach process 74225 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.6.2
main_class
pid        74225
time       2022-06-28 14:17:30

离线安装 Arthas

离线环境无法通过 java -jar arthas-boot.jar 自动安装,会报错:

[ERROR] Can not read arthas version from: https://arthas.aliyun.com/api/latest_version
[ERROR] Can not find Arthas under local: /root/.arthas/lib and remote repo mirror: aliyun
[ERROR] Unable to download arthas from remote server, please download the full package according to wiki: https://github.com/alibaba/arthas

从 阿里云 或 GitHub 下载得到 arthas-packaging-3.6.2-bin.zip
https://arthas.aliyun.com/download/latest_version?mirror=aliyun
https://github.com/alibaba/arthas/releases/download/arthas-all-3.6.3/arthas-bin.zip

unzip arthas-packaging-3.6.2-bin.zip -d arthas 解压到 arthas 目录,里面有 arthas-boot.jar 及需要的其他全量工具。

还是 java -jar arthas-boot.jar 启动,不会再重新下载,直接即可 attach 到进程上

# java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.6.2
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 6 /root/apps/app/lib/app-exporter-2.0.0-SNAPSHOT.jar
1
[INFO] arthas home: /root/logs/arthas-3.6.2
[INFO] Try to attach process 6
[INFO] Attach process 6 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.6.2
main_class
pid        6
time       2022-06-28 14:43:54

上一篇 Milvus

下一篇 Eclipse-MAT

阅读
评论
2.4k
阅读预计12分钟
创建日期 2022-06-26
修改日期 2022-07-01
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论