乐趣区

关于程序员:Arthas-一款释放潜力的神器

大家好,我是 Yuan,明天给大家介绍一款调优神器 — 阿里巴巴 Arthas,能够帮忙你的利用开释后劲。

1. 介绍

阿里巴巴 Arthas 是一个诊断工具,能够用于监督、剖析和解决 Java 应用程序的问题。应用 Arthas 的一个次要长处是,咱们不须要批改代码,甚至不须要重新启动咱们想要监督的 Java 服务。

在本教程中,咱们将首先装置 Arthas,在此之后,通过一个简略的案例来演示 Arthas 的一些要害个性。

最初,因为 Arthas 是用 Java 编写的,因而它是跨平台的,能够在 Linux、macOS 和 Windows 上运行。

2. 下载和入门

首先,咱们能够通过间接下载链接或应用 curl 来下载 Arthas 库:

curl -O https://alibaba.github.io/arthas/arthas-boot.jar

当初,让咱们通过运行带有 -h(帮忙)选项的 Arthas 来测试它是否工作:

java -jar arthas-boot.jar -h

如果胜利,咱们应该看到显示所有命令的帮忙指南:

3. 案例剖析

在本教程中,咱们将应用一个非常简单的应用程序,基于利用递归实现的斐波那契数列的绝对低效的实现形式:

public class FibonacciGenerator {public static void main(String[] args) {System.out.println("按任意键持续");
        System.in.read();
        for (int i = 0; i < 100; i++) {long result = fibonacci(i);
            System.out.println(format("fib(%d): %d", i, result));
        }
    }

    public static long fibonacci(int n) {if (n == 0 || n == 1) {return 1L;} else {return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
}

这个示例的最乏味的局部是遵循斐波那契数列的数学定义的 fibonacci 办法。

在 main 办法中,咱们应用一个循环和绝对较大的数字,以便让计算机进行较长时间的计算。这当然正是咱们想要的,以便演示 Arthas。

4. 启动 Arthas

当初让咱们试试 Arthas!咱们须要做的第一件事是运行咱们的小型斐波那契应用程序。咱们能够应用咱们喜爱的 IDE 或间接在终端中运行它。它会要求按下一个键能力启动。咱们将在将过程附加到 Arthas 之后按下任意键。

当初,让咱们运行 Arthas 可执行文件:

java -jar arthas-boot.jar

Arthas 提醒抉择要附加到的过程:

[INFO] arthas-boot version: 3.1.7
[INFO] Found existing java process, please choose one and hit RETURN.
* [1]: 25500 com.baeldung.arthas.FibonacciGenerator
...

让咱们抉择名称为 com.baeldung.arthas.FibonacciGenerator 的过程。在此示例中,只需在列表中输出数字‘1’并按 Enter 即可。

Arthas 当初会附加到该过程并启动:

[INFO] Try to attach process 25500
[INFO] Attach process 25500 success.
...                     

一旦 Arthas 启动,咱们就有一个提示符,能够收回不同的命令。

咱们能够应用 help 命令获取无关可用选项的更多信息。为了方便使用 Arthas,咱们还能够应用 tab 键来主动实现其命令。

在将 Arthas 附加到过程后,咱们当初能够按下一个键,程序将开始打印斐波那契数。

5. 仪表盘

一旦 Arthas 启动,咱们能够应用仪表盘。在这种状况下,咱们通过输出 “dashboard” 命令来应用仪表盘。当初,咱们能够看到一个具体的屏幕,其中蕴含多个面板和对于咱们的 Java 过程的许多信息:

让咱们更具体地看一下其中的一些内容:

  • 顶部区域专门显示以后正在运行的线程
  • 一个重要的列是每个线程的 CPU 应用状况
  • 第三局部显示每个线程的 CPU 工夫
  • 另一个乏味的面板是内存剖析。不同的内存区域以及它们的统计信息都列在其中。在右侧,咱们有垃圾收集器的信息
  • 最初,在第五局部,咱们有对于主机平台和 JVM 的信息

咱们能够通过按下 “q” 键退出仪表盘。

咱们应该记住,即便退出,Arthas 仍会附加到咱们的过程上。因而,为了正确地从咱们的过程中断开它的连贯,咱们须要运行 “stop” 命令。

6. 剖析堆栈跟踪

在仪表盘中,咱们看到咱们的主过程占用了简直 100% 的 CPU。该过程的 ID 是 1,在第一列中能够看到。

当初咱们曾经退出了仪表盘,咱们能够通过 运行 “thread” 命令 来更具体地剖析该过程:

thread 1

作为参数传递的数字是线程 ID。Arthas 打印出一个堆栈跟踪信息,其中充斥着对 fibonacci 办法的调用。

如果堆栈跟踪信息很长而且难以浏览,能够应用 “thread” 命令联合 “grep” 命令来过滤:

thread 1 | grep 'main('

这将只打印与 “grep” 命令匹配的行:

[arthas@25500]$ thread 1 | grep 'main('
    at com.baeldung.arthas.FibonacciGenerator.main(FibonacciGenerator.java:10)

7. 反编译 Java 类

假如咱们正在剖析一个咱们对其中理解甚少或无所不知的 Java 应用程序,忽然发现堆栈中充斥着以下类型的反复调用:

[arthas@59816]$ thread 1
"main" Id=1 RUNNABLE
  at app//com.baeldung.arthas.FibonacciGenerator.fibonacci(FibonacciGenerator.java:18)
  at app//com.baeldung.arthas.FibonacciGenerator.fibonacci(FibonacciGenerator.java:18)
  ...

因为咱们运行了 Arthas,咱们能够反编译一个类来查看其内容。为了实现这一点,咱们能够应用 jad 命令,将限定类名作为参数传递:

jad com.baeldung.arthas.FibonacciGenerator

类加载器:+-jdk.internal.loader.ClassLoaders $ AppClassLoader @ 799f7e29
  +-jdk.internal.loader.ClassLoaders $ PlatformClassLoader @ 60f1dd34

地位:/home/amoreno/work/baeldung/tutorials/libraries-3/target/
/*
 * 反编译应用 CFR。*/
package com.baeldung.arthas;

import java.io.IOException;
import java.io.InputStream;
importjava.io.PrintStream;

public class FibonacciGenerator {public static void main(String[] arrstring) throws IOException {

输入是反编译的 Java 类和一些有用的元数据,如类的地位。这是一个十分有用和弱小的性能。

8. 搜寻类和搜寻办法

搜寻类命令在搜寻 JVM 中加载的类时十分不便。咱们能够应用它通过输出 sc 并将模式作为参数传递来应用,带或不带通配符:

[arthas@70099]$ sc *Fibonacci*
com.baeldung.arthas.FibonacciGenerator
Affect(row-cnt:1) cost in 5 ms.

一旦咱们取得了类的限定名称,咱们能够应用两个附加标记来查找更多信息:

  • - d 显示类的详细信息
  • - f 显示类的字段

然而,类的字段必须与详细信息一起查问:

[arthas@70099]$ sc -df com.baeldung.arthas.FibonacciGenerator
  class-info        com.baeldung.arthas.FibonacciGenerator
  ...

同样,咱们能够应用 sm(搜寻办法)命令来查找类中加载的办法。在这种状况下,对于咱们的类 com.baeldung.arthas.FibonacciGenerator,咱们能够运行:

[arthas@70099]$ sm com.baeldung.arthas.FibonacciGenerator
com.baeldung.arthas.FibonacciGenerator <init>()V
com.baeldung.arthas.FibonacciGenerator main([Ljava/lang/String;)V
com.baeldung.arthas.FibonacciGenerator fibonacci(I)J
Affect(row-cnt:3) cost in 4 ms.

咱们能够应用 - d 标记来检索办法的详细信息。最初,咱们能够传递办法的名称作为可选参数,以放大返回办法的数量:

sm -d com.baeldung.arthas.FibonacciGenerator fibonacci
 declaring-class  com.baeldung.arthas.FibonacciGenerator
 method-name      fibonacci
 modifier         public,static
 annotation
 parameters       int
 return           long
 exceptions
 classLoaderHash  799f7e29

9. 监督办法调用

咱们能够应用 Arthas 来监督办法,这在调试应用程序的性能问题时十分不便。为此,咱们能够应用 monitor 命令。

monitor 命令须要一个 -c < 秒数 > 标记和两个参数 – 限定类名和办法名。

对于咱们的案例钻研,让咱们来调用 monitor:

monitor -c 10 com.baeldung.arthas.FibonacciGenerator fibonacci

正如咱们所预期的,Arthas 将每 10 秒打印无关 fibonacci 办法的指标:

Affect(class-cnt:1 , method-cnt:1) cost in 47 ms.
 timestamp            class                                          method     total   success  fail  avg-rt(ms)  fail-rate                                                                       
-----------------------------------------------------------------------------------------------------------------------------                                                                      
 2020-03-07 11:43:26  com.baeldung.arthas.FibonacciGenerator  fibonacci  528957  528957   0     0.07        0.00%
...                                                                           

对于那些最终失败的调用,咱们也有指标 – 这对于调试很有用。

10. 监控办法参数

如果咱们须要调试办法的参数,咱们能够应用 watch 命令。然而,语法会略微简单一些:

watch com.baeldung.arthas.FibonacciGenerator fibonacci '{params[0], returnObj}' 'params[0]>10' -n 10

让咱们具体看一下各个参数:

  • 第一个参数是类名
  • 第二个参数是办法名
  • 第三个参数是定义咱们要查看的内容的 OGNL 表达式 – 在这种状况下,它是第一个(也是惟一的)办法参数和返回值
  • 第四个和最初一个可选参数是用于过滤咱们要监督的调用的布尔表达式

对于此示例,咱们只想在参数大于 10 时监督。最初,咱们增加一个标记来限度后果为 10 个:

watch com.baeldung.arthas.FibonacciGenerator fibonacci '{params[0], returnObj}' 'params[0]>10' -n 10
按 Q 或 Ctrl+ C 中断。Affect(class-cnt:1 , method-cnt:1) cost in 19 ms.
ts=2020-02-17 21:48:08; [cost=30.165211ms] result=@ArrayList[@Integer[11],
    @Long[144],
]
ts=2020-02-17 21:48:08; [cost=50.405506ms] result=@ArrayList[@Integer[12],
    @Long[233],
]
...

在这里,咱们能够看到带有 CPU 工夫和输出 / 返回值的调用示例。

11. 分析器

对于那些对应用程序性能感兴趣的人来说,通过分析器命令提供了一种十分直观的能力。分析器将评估咱们的过程正在应用的 CPU 的性能。

让咱们通过运行 profiler start 来启动分析器。这是一个非阻塞的工作,意味着在分析器工作时咱们能够持续应用 Arthas。

随时能够通过运行 profiler getSamples 来询问分析器有多少个样本。

当初让咱们应用 profiler stop 来进行分析器。此时,一个 FlameGraph 图像将被保留。在这个具体的案例中,咱们有一个以斐波那契线程为主导的图表:

留神,当咱们想要检测咱们的 CPU 工夫花在哪里时,这个图表特地有用。

12. 总结

在本教程中,咱们摸索了 Arthas 的一些最弱小和有用的性能。

正如咱们所见,Arthas 有许多命令能够帮忙咱们诊断各种问题。当咱们无法访问正在审查的应用程序的代码,或者咱们想疾速诊断在服务器上运行的有问题的应用程序时,它也能够特地有帮忙。

参考资料:

  1. 官网文档:https://arthas.aliyun.com/doc/
  2. Arthas 的 GitHub 仓库地址:https://github.com/alibaba/arthas

本文由 mdnice 多平台公布

退出移动版