美文网首页JVMJavajava~知识
Arthas - Java诊断神器

Arthas - Java诊断神器

作者: 十毛tenmao | 来源:发表于2019-03-06 22:32 被阅读128次

    Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。

    当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

    • 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
    • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
    • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
    • 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
    • 是否有一个全局视角来查看系统的运行状况?
    • 有什么办法可以监控到JVM的实时运行状态?

    启动图

    Arthas

    快速使用

    Arthas无需安装,下载就可以直接使用

    • 下载&启动
    wget https://alibaba.github.io/arthas/arthas-boot.jar
    java -jar arthas-boot.jar
    

    常用场景

    • 这个类从哪个 jar 包加载的?

    sc -d {className} 支持通配符,从code-source可以看出来类从哪个jar包加载的

    sc -d *MathGame
    
    $ 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@55f96302
                         +-sun.misc.Launcher$ExtClassLoader@378df983
     classLoaderHash   55f96302
    
    • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
      jad {className}
    jad demo.MathGame
    
    $ jad demo.MathGame
    
    ClassLoader:
    +-sun.misc.Launcher$AppClassLoader@55f96302
      +-sun.misc.Launcher$ExtClassLoader@378df983
    
    Location:
    /home/scrapbook/tutorial/arthas-demo.jar
    
    /*
     * Decompiled with CFR 0_132.
     */
    package demo;
    
    import java.io.PrintStream;
    import java.util.ArrayList;
    import java.util.Iterator;
    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) {
    
    • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?

      监控方法入参、返回值、成员变量

    watch demo.MathGame primeFactors "{params, target, returnObj, throwExp}" -x 2 -n 2
    
    $ watch demo.MathGame primeFactors "{params, target, returnObj, throwExp}" -x 2 -n 2
    Press Q or Ctrl+C to abort.
    Affect(class-cnt:1 , method-cnt:1) cost in 75 ms.
    ts=2019-03-06 14:09:40; [cost=0.284671ms] result=@ArrayList[
        @Object[][
            @Integer[51463],
        ],
        @MathGame[
            random=@Random[java.util.Random@1a6c5a9e],
            illegalArgumentCount=@Integer[1230],
        ],
        @ArrayList[
            @Integer[53],
            @Integer[971],
        ],
        null,
    ]
    ts=2019-03-06 14:09:41; [cost=0.09573ms] result=@ArrayList[
        @Object[][
            @Integer[133515],
        ],
        @MathGame[
            random=@Random[java.util.Random@1a6c5a9e],
            illegalArgumentCount=@Integer[1230],
        ],
        @ArrayList[
            @Integer[3],
            @Integer[3],
            @Integer[3],
            @Integer[5],
            @Integer[23],
            @Integer[43],
        ],
        null,
    ]
    
    • 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!

    方法同上,不过可以增加参数过滤,针对特定用户查看调用情况

    watch demo.MathGame primeFactors "{params, target, returnObj, throwExp}" "params[0] < 0" -x 2 -n 2
    

    其中params[0]<0就是过滤条件

    $ watch demo.MathGame primeFactors "{params, target, returnObj, throwExp}" "params[0] < 0" -x 2 -n 2
    Press Q or Ctrl+C to abort.
    Affect(class-cnt:1 , method-cnt:1) cost in 101 ms.
    ts=2019-03-06 14:14:24; [cost=0.211055ms] result=@ArrayList[
        @Object[][
            @Integer[-212657],
        ],
        @MathGame[
            random=@Random[java.util.Random@1a6c5a9e],
            illegalArgumentCount=@Integer[1377],
        ],
        null,
        java.lang.IllegalArgumentException: number is: -212657, need >= 2
            at demo.MathGame.primeFactors(MathGame.java:46)
            at demo.MathGame.run(MathGame.java:24)
            at demo.MathGame.main(MathGame.java:16)
    ,
    ]
    ts=2019-03-06 14:14:25; [cost=0.111067ms] result=@ArrayList[
        @Object[][
            @Integer[-197020],
        ],
        @MathGame[
            random=@Random[java.util.Random@1a6c5a9e],
            illegalArgumentCount=@Integer[1378],
        ],
        null,
        java.lang.IllegalArgumentException: number is: -197020, need >= 2
            at demo.MathGame.primeFactors(MathGame.java:46)
            at demo.MathGame.run(MathGame.java:24)
            at demo.MathGame.main(MathGame.java:16)
    ,
    ]
    
    • 是否有一个全局视角来查看系统的运行状况?
      dashboar

      dashboard
    • 有什么办法可以监控到JVM的实时运行状态?
      jvm

      JVM

    基本命令

    • help: 帮助,而且每个命令都提供了帮助选项(-h),比如watch -h
    • keymap:查看快捷键
    • thread 1: 查看线程栈
    • exit/quit: 退出当前session, arthas server还在目标进程中运行
    • shutdown: 完全退出Arthas

    其他高级用法

    watch

    • 当异常时捕获
      watch命令支持-e选项,表示只捕获抛出异常时的请求:
    watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e
    
    • 按照耗时进行过滤
      watch命令支持按请求耗时进行过滤,比如:
    watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'
    

    参考

    相关文章

      网友评论

        本文标题:Arthas - Java诊断神器

        本文链接:https://www.haomeiwen.com/subject/wkkfpqtx.html