java使用Arthas线上诊断
  DF5J4hb0hcmT 2023年12月07日 48 0

安装使用

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

执行该程序的用户需要和目标进程具有相同的权限,最好和目标进程的用户一致

启动以后,输入 数字 选择要观察的进程,也可增加--select jar名称自动选择进程,提高操作效率

还可以在 末尾增加 进程号(启动后也不用选择进程了)

查看 dashboard

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

java使用Arthas线上诊断_java

watch

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

java使用Arthas线上诊断_arthas_02

观察指定函数的调用情况,如 入参、返回值、抛出异常,通过编写 OGNL 表达式查看

命令格式:watch 类全名或类名表达式 函数名表达式 {观察表达式} -x 输出深度 -n 次数

观察表达式:默认 {params, target, returnObj},分别是 参数列表、被观察对象、返回值

-x 输出深度:默认为 1,最大为 4。默认的 观察表达式中 params + 输出深度 1,只能输出 params 是否 empty,size 是 几,要看到内容就要加大 输出深度 或 改为 params[0]

很多时候,我们都不关注 被观察对象 target,指定 观察表达式 可以降低干扰,尤其是 属性多 或 输出深度大的时候

观察执行频繁的方法,最好指定 -n 次数,避免刷屏

条件表达式的例子

只有满足条件的调用,才会有响应。第一个参数值小于0才显示。

[arthas@421]$ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 20 ms, listenerId: 2
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2023-12-07 15:06:54; [cost=0.122501ms] result=@ArrayList[
    @Integer[-162810],
    @MathGame[demo.MathGame@5910e440],
]
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2023-12-07 15:06:56; [cost=0.023808ms] result=@ArrayList[
    @Integer[-26281],
    @MathGame[demo.MathGame@5910e440],
]

重载todo

重载方法,可通过参数 个数、类型 筛选

命令格式:watch 类全名或类名表达式 函数名表达式 {观察表达式} 'params.length== 参数个数 && params[1] instanceof java.lang.String

[arthas@22882]$ watch demo.MathGame primeFactors "{params[0],params[1],target}" "params.length==2 && params[1] instanceof java.lang.String"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 2) cost in 15 ms, listenerId: 15
method=demo.MathGame.primeFactors location=AtExit
ts=2023-12-07 15:30:10; [cost=0.225008ms] result=@ArrayList[
    @Integer[1],
    @String[cz],
    @MathGame[demo.MathGame@533ddba],
]

退出 arthas

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

如果想完全退出 arthas,可以执行stop命令。


源码:

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) {
            game.run();
            TimeUnit.SECONDS.sleep(1);
            game.run1();
            TimeUnit.SECONDS.sleep(1);
        }
    }

    public void run() throws InterruptedException {
        try {
            int number = random.nextInt() / 10000;
            List<Integer> primeFactors = primeFactors(number);
            print(number, primeFactors);

        } catch (Exception e) {
            System.out.println(String.format("illegalArgumentCount:%3d, ", illegalArgumentCount) + e.getMessage());
        }
    }

    public void run1() throws InterruptedException {
        try {
            int number = random.nextInt() / 10000;
            List<Integer> primeFactors = primeFactors(number, "cz");
            print(number, primeFactors);

        } catch (Exception e) {
            System.out.println(String.format("illegalArgumentCount:%3d, ", 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('*');
        }
        if (sb.charAt(sb.length() - 1) == '*') {
            sb.deleteCharAt(sb.length() - 1);
        }
        System.out.println(sb);
    }

    public List<Integer> primeFactors(int number) {
        if (number < 2) {
            illegalArgumentCount++;
            throw new IllegalArgumentException("number is: " + number + ", need >= 2");
        }

        List<Integer> result = new ArrayList<Integer>();
        int i = 2;
        while (i <= number) {
            if (number % i == 0) {
                result.add(i);
                number = number / i;
                i = 2;
            } else {
                i++;
            }
        }

        return result;
    }

    public List<Integer> primeFactors(int number, String name) {
        System.out.println("number:" + number + "primeFactors override method");
        if (number < 2) {
            illegalArgumentCount++;
            throw new IllegalArgumentException("number is: " + number + ", need >= 2");
        }

        List<Integer> result = new ArrayList<Integer>();
        int i = 2;
        while (i <= number) {
            if (number % i == 0) {
                result.add(i);
                number = number / i;
                i = 2;
            } else {
                i++;
            }
        }

        return result;
    }
}

https://zhuanlan.zhihu.com/p/651456569 

https://arthas.aliyun.com/doc/quick-start.html#_6-watch

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月07日 0

暂无评论

推荐阅读
  3I1N9ysrcSyk   2023年12月08日   26   0   0 javahapi数据交换
  DF5J4hb0hcmT   2023年12月07日   49   0   0 javaArthas
DF5J4hb0hcmT