Arthas之trace、monitor、watch命令

Arthas是Alibaba开源的一款Java诊断工具,其提供了丰富的命令。这里介绍其中的trace、monitor、watch命令

Arthas之trace、monitor、watch命令

abstract.png

trace

可以跟踪指定方法调用的耗时,为便于演示,提供下述测试代码

package com.aaron.Arthas;

import org.junit.Test;

public class TestTrace {

    @Test
    public void testMain() throws InterruptedException {
        while (true) {
            addUserController();
        }
    }

    // 49秒
    private void addUserController() throws InterruptedException {
        serviceA();                       // 15秒
        serviceB();                       // 24秒
        Thread.sleep(10 * 1000);    // 10秒
    }

    // 15秒
    private void serviceA() throws InterruptedException {
        Thread.sleep( 3 * 1000); // 3秒
        add2Mysql();                   // 8秒
        add2Redis();                   // 4秒
    }

    // 24秒
    private void serviceB() throws InterruptedException {
        Thread.sleep(20 * 1000); // 20秒
        add2Redis();                   // 4秒
    }

    // 8秒
    private void add2Mysql() throws InterruptedException {
        Thread.sleep( 8 * 1000 );
    }

    // 4秒
    private void add2Redis() throws InterruptedException {
        Thread.sleep( 4 * 1000 );
    }
}

「基本实践」

该命令用法如下所示

# 跟踪指定类的指定方法中的耗时
trace <类名> <方法名>

# 跟踪com.aaron.Arthas.TestTrace类中addUserController方法的耗时
trace com.aaron.Arthas.TestTrace addUserController

# 跟踪com.aaron.Arthas.TestTrace类中addUserController方法的耗时,-n选项指定捕捉结果的次数
trace -n 5 com.aaron.Arthas.TestTrace addUserController

不难看出,trace命令只会跟踪、统计被匹配到的函数里的子调用,并不会向下trace多层

Arthas之trace、monitor、watch命令

figure 1.jpeg

「统计JDK方法调用」

默认情况下,trace结果中不会对JDK方法调用进行耗时统计。故如果期望含有对JDK方法调用的耗时统计,需显式使用 「–skipJDKMethod false」 选项

# 跟踪com.aaron.Arthas.TestTrace类中addUserController方法的耗时,同时包含对JDK方法调用的统计
trace --skipJDKMethod false com.aaron.Arthas.TestTrace addUserController

Arthas之trace、monitor、watch命令

figure 2.jpeg

「支持正则匹配」

trace命令提供了-E选项,可以通过正则表达式来匹配多个类、方法。在一定程度上可以达到实现多层trace对效果

# 跟踪com.aaron.Arthas.TestTrace类中addUserController、serviceA、serviceB方法的耗时
trace -E com.aaron.Arthas.TestTrace addUserController|serviceA|serviceB

Arthas之trace、monitor、watch命令

figure 3.jpeg
# 跟踪com.aaron.Arthas.TestTrace类中方法名以add2开头的方法耗时
trace -E com.aaron.Arthas.TestTrace add2.*

Arthas之trace、monitor、watch命令

figure 4.jpeg

「动态trace」

我们在终端1对addUserController进行trace,从下述输出中不难看出,其listenerId为7

Arthas之trace、monitor、watch命令

figure 5.jpeg

假设我们现在期望对serviceA方法中的调用耗时进行分析,则可以在终端2中,先使用telnet连接Arthas,然后使用trace命令跟踪serviceA方法。与此同时在trace命令中使用–listenerId选项指定在终端1中看到的listenerId值即可

# 终端2的命令
telnet localhost 3658
trace com.aaron.Arthas.TestTrace serviceA --listenerId 7

Arthas之trace、monitor、watch命令

figure 6.jpeg

现在我们回到终端1进行观察,即会发现输出结果中包含了对servcieA方法的调用耗时分析结果。事实上通过这种方式,我们可以不断按需深入trace

Arthas之trace、monitor、watch命令

figure 7.jpeg

monitor

该命令可以对方法进行监控,监控指标包括调用次数、成功次数、失败次数、平均RT(平均响应时间)、失败率。其中这里失败的判定标准为方法执行抛出异常。这里提供如下的测试代码

package com.aaron.Arthas;

import org.junit.Test;
import java.util.Random;

public class TestMonitor {
    @Test
    public void test1() {
        Random random = new Random();
        while (true) {
            try {
                if( random.nextInt(10) < 5 ) {
                    calc(true);
                } else {
                    calc(false);
                }
            } catch (Exception e) {
            }
        }
    }

    private void calc(boolean flag) throws InterruptedException {
        if( flag==true ) {
            throw new RuntimeException();
        } else {
            Thread.sleep( 700 );
        }
    }
}

使用方式很简单,指定类名、方法名即可。同时-c选项表示统计周期,单位为秒。默认为120秒

monitor -c 5  com.aaron.Arthas.TestMonitor calc

Arthas之trace、monitor、watch命令

figure 8.jpeg

还可以通过-b选项搭配条件表达式,实现对特定场景下的方法调用进行统计

# 对TestMonitor的calc方法,当第一个参数值为false时进行监控
monitor -b -c 5  com.aaron.Arthas.TestMonitor calc "params[0] == false"

# 对TestMonitor的calc方法,当第一个参数值为true时进行监控
monitor -b -c 5  com.aaron.Arthas.TestMonitor calc "params[0] == true"

Arthas之trace、monitor、watch命令

figure 9.jpeg

watch

便于观察指定方法的调用情况。具体地,可以观察到:方法入参、方法返回值、方法抛出异常。故watch命令定义了4个观察事件点。并提供了对应的方法选项

「-b」:在方法被调用前进行观察。当使用该选项时,由于观察事件点是在方法被调用之前,此时方法的返回值或异常均无法观察到。即只能观察到方法的入参「-e」:在方法调用抛出异常时,进行观察。「-s」:在方法调用正常返回时,进行观察。「-f」:在方法调用结束后进行观察。显然该选项即会观察到方法抛出异常的情形,也会观察到方法正常返回的情形。除了该选项默认打开外,上述3个选项均默认关闭

为了便于演示,提供下述测试代码

package com.aaron.Arthas;

import org.junit.Test;
import java.util.Random;

public class TestWatch {
    private static final String AUTHOR = "Aaron Zhu";

    private Random random;

    @Test
    public void test1() {
        random = new Random();
        while (true) {
            try {
                Thread.sleep(1000);
                int num = random.nextInt(10);
                String msg = calc(num, "Hello, ");
                System.out.println(msg);
            } catch (Exception e) {
            }
        }
    }

    private String calc(int num, String info) {
        String res = null;
        if( num>=0 && num<=2 ) {
            throw new IllegalArgumentException("Number is Error !!");
        } else if ( num>=3 && num<=5 ) {
            res = "Dog : " + num;
        }  else if ( num>=6 && num<=9 ) {
            res = "Cat :" + num;
        }

        res = info + res;
        return res;
    }

}

「观察方法调用时的入参」

我们通过 「-b选项」 观察TestWatch中calc方法被调用时的方法入参,同时指定观察表达式 「{params,target,returnObj}」 ,其中params、target、returnObj分别表示入参、调用类的实例、返回值。「-x选项」 则用于指定对输出结果中属性遍历的深度,默认为1,最大为4

# 通过-b选项观察TestWatch中calc方法被调用时的方法入参
watch -b -x 2 com.aaron.Arthas.TestWatch calc "{params,target,returnObj}"

下述红框表示观察表达式的第1个元素params,即方法的入参;下述蓝框表示观察表达式的第2个元素target,即调用方法的实例;下述蓝框表示观察表达式的第3个元素returnObj,即方法的出参。此外输出结果的location值为「AtEnter」,表示观察事件的位置在函数入口

Arthas之trace、monitor、watch命令

figure 10.jpeg

「观察方法调用时的返回值」

# 通过-s选项观察TestWatch中calc方法被调用时的方法入参、返回值
watch -s -x 2 com.aaron.Arthas.TestWatch calc "{params,target,returnObj}"

此外输出结果的location值为「AtExit」,表示观察事件的位置在函数正常返回

Arthas之trace、monitor、watch命令

figure 11.jpeg

「观察方法调用时抛出的异常」

在观察表达式中,可使用throwExp表示异常信息

# 通过-e选项观察TestWatch中calc方法被调用时的方法入参、抛出的异常
watch -e -x 2 com.aaron.Arthas.TestWatch calc "{params,target,throwExp}"

此外输出结果的location值为「AtExceptionExit」,表示观察事件的位置在函数抛出异常

Arthas之trace、monitor、watch命令

figure 12.jpeg

「观察方法调用的结果」

# 通过-f选项观察TestWatch中calc方法被调用后的结果(包含正常返回、抛出异常两种情形)
watch -f -x 2 com.aaron.Arthas.TestWatch calc "{params,target,returnObj,throwExp}"

Arthas之trace、monitor、watch命令

figure 13.jpeg

「使用条件表达式进行过滤」

我们还可以通过条件表达式实现仅对我们期望的场景进行观察,以免输出结果太多造成干扰

# 对TestWatch中calc方法进行观察, 同时要求 方法第一个参数的值大于2 且 方法第一个参数值为偶数 时才进行观察
watch -f -x 2 com.aaron.Arthas.TestWatch calc "{params,target,returnObj,throwExp}" "params[0]>2 && params[0]%2==0"

Arthas之trace、monitor、watch命令

figure 14.jpeg

原文始发于微信公众号(青灯抽丝):Arthas之trace、monitor、watch命令

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/156443.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!