• 阿尔萨斯(Arthas)入门


    简介

    Arthas(阿尔萨斯) 能为你做什么

    Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。
    当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

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

    Arthas支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

    安装

    快速安装

    使用arthas-boot(推荐)
    下载arthas-boot.jar,然后用java -jar的方式启动:

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

    打印帮助信息:

    java -jar arthas-boot.jar -h
    
    • 如果下载速度比较慢,可以使用aliyun的镜像:
    java -jar arthas-boot.jar --repo-mirror aliyun --use-http
    

    全量安装

    最新版本,点击下载:Arthas
    解压后,在文件夹里有arthas-boot.jar,直接用java -jar的方式启动:

    java -jar arthas-boot.jar
    

    执行该程序的用户需要和目标进程具有相同的权限。比如以admin用户来执行:sudo su admin && java -jar arthas-boot.jar 或 sudo -u admin -EH java -jar arthas-boot.jar。
    如果attach不上目标进程,可以查看~/logs/arthas/ 目录下的日志。
    打印帮助信息:

    java -jar arthas-boot.jar -h
    

    卸载

    • 在 Linux/Unix/Mac 平台
      删除下面文件:
    rm -rf ~/.arthas/
    rm -rf ~/logs/arthas
    
    • Windows平台直接删除user home下面的.arthaslogs/arthas目录

    使用

    启动arthas

    接上面启动arthas后,界面显示如下,选择应用java进程:

    $ $ java -jar arthas-boot.jar
    * [1]: 35542
      [2]: 71560 arthas-demo.jar
    

    Demo进程是第2个,则输入2,再输入回车/enter。Arthas会attach到目标进程上,并输出日志:

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

    查看dashboard

    输入dashboard,按回车/enter,会展示当前进程的信息,按ctrl+c可以中断执行。

    $ dashboard
    ID     NAME                   GROUP          PRIORI STATE  %CPU    TIME   INTERRU DAEMON
    17     pool-2-thread-1        system         5      WAITIN 67      0:0    false   false
    27     Timer-for-arthas-dashb system         10     RUNNAB 32      0:0    false   true
    11     AsyncAppender-Worker-a system         9      WAITIN 0       0:0    false   true
    9      Attach Listener        system         9      RUNNAB 0       0:0    false   true
    3      Finalizer              system         8      WAITIN 0       0:0    false   true
    2      Reference Handler      system         10     WAITIN 0       0:0    false   true
    4      Signal Dispatcher      system         9      RUNNAB 0       0:0    false   true
    26     as-command-execute-dae system         10     TIMED_ 0       0:0    false   true
    13     job-timeout            system         9      TIMED_ 0       0:0    false   true
    1      main                   main           5      TIMED_ 0       0:0    false   false
    14     nioEventLoopGroup-2-1  system         10     RUNNAB 0       0:0    false   false
    18     nioEventLoopGroup-2-2  system         10     RUNNAB 0       0:0    false   false
    23     nioEventLoopGroup-2-3  system         10     RUNNAB 0       0:0    false   false
    15     nioEventLoopGroup-3-1  system         10     RUNNAB 0       0:0    false   false
    Memory             used   total max    usage GC
    heap               32M    155M  1820M  1.77% gc.ps_scavenge.count  4
    ps_eden_space      14M    65M   672M   2.21% gc.ps_scavenge.time(m 166
    ps_survivor_space  4M     5M    5M           s)
    ps_old_gen         12M    85M   1365M  0.91% gc.ps_marksweep.count 0
    nonheap            20M    23M   -1           gc.ps_marksweep.time( 0
    code_cache         3M     5M    240M   1.32% ms)
    Runtime
    os.name                Mac OS X
    os.version             10.13.4
    java.version           1.8.0_162
    java.home              /Library/Java/JavaVir
                           tualMachines/jdk1.8.0
                           _162.jdk/Contents/Hom
                           e/jre
    

    通过thread命令来获取到arthas-demo进程的Main Class

    thread 1会打印线程ID 1的栈,通常是main函数的线程。

    $ thread 1 | grep 'main('
        at demo.MathGame.main(MathGame.java:17)
    

    通过jad来反编译Main Class

    $ jad demo.MathGame
     
    ClassLoader:
    +-sun.misc.Launcher$AppClassLoader@3d4eac69
      +-sun.misc.Launcher$ExtClassLoader@66350f69
     
    Location:
    /tmp/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();
        private int illegalArgumentCount = 0;
     
        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();
                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 + "=");
            Iterator<Integer> iterator = primeFactors.iterator();
            while (iterator.hasNext()) {
                int factor = iterator.next();
                sb.append(factor).append('*');
            }
            if (sb.charAt(sb.length() - 1) == '*') {
                sb.deleteCharAt(sb.length() - 1);
            }
            System.out.println(sb);
        }
     
        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;
        }
    }
     
    Affect(row-cnt:1) cost in 970 ms.
    

    watch

    通过watch命令来查看demo.MathGame#primeFactors函数的返回值:

    $ watch demo.MathGame primeFactors returnObj
    Press Ctrl+C to abort.
    Affect(class-cnt:1 , method-cnt:1) cost in 107 ms.
    ts=2018-11-28 19:22:30; [cost=1.715367ms] result=null
    ts=2018-11-28 19:22:31; [cost=0.185203ms] result=null
    ts=2018-11-28 19:22:32; [cost=19.012416ms] result=@ArrayList[
        @Integer[5],
        @Integer[47],
        @Integer[2675531],
    ]
    ts=2018-11-28 19:22:33; [cost=0.311395ms] result=@ArrayList[
        @Integer[2],
        @Integer[5],
        @Integer[317],
        @Integer[503],
        @Integer[887],
    ]
    ts=2018-11-28 19:22:34; [cost=10.136007ms] result=@ArrayList[
        @Integer[2],
        @Integer[2],
        @Integer[3],
        @Integer[3],
        @Integer[31],
        @Integer[717593],
    ]
    ts=2018-11-28 19:22:35; [cost=29.969732ms] result=@ArrayList[
        @Integer[5],
        @Integer[29],
        @Integer[7651739],
    ]
    

    更多的功能可以查看进阶使用

    退出arthas

    如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
    如果想完全退出arthas,可以执行stop命令。

    F&Q

    定位问题原因* 根据原因思考问题解决方案* 实践验证方案有效性* 提交验证结果
  • 相关阅读:
    HDU 1423 Greatest Common Increasing Subsequence(LICS入门,只要求出最长数)
    HDU 5455 Fang Fang
    hihoCoder 1234 fractal
    二叉排序树
    最大连续子序列和,最大上升子序列和,最长上升子序列,最长公共子串,最长公共子序列,最长上升公共子序列
    C++ string string string string string string string string string string
    pip安装第三方库
    pip安装时使用国内源,加快下载速度
    pip升级命令
    instanceof -- JS
  • 原文地址:https://www.cnblogs.com/jimoliunian/p/13968507.html
Copyright © 2020-2023  润新知