1. Introduction
1.绪论
Alibaba Arthas is a diagnostic tool that enables us to monitor, profile, and troubleshoot our Java applications. One of the key benefits of using Arthas is that we don’t need to change our code or even restart the Java services that we want to monitor.
Alibaba Arthas是一个诊断工具,它使我们能够监控、剖析我们的 Java 应用程序并排除故障。使用Arthas的一个主要好处是,我们不需要改变我们的代码,甚至不需要重新启动我们想要监控的Java服务。
In this tutorial, we’ll start by installing Arthas before we walk through a simple case study to demonstrate some of the key features of Arthas.
在本教程中,我们将首先安装Arthas,然后通过一个简单的案例研究来展示Arthas的一些关键功能。
Finally, as Arthas is written in Java, it’s cross-platform and will happily run on Linux, macOS, and Windows.
最后,由于Arthas是用Java编写的,它是跨平台的,可以愉快地在Linux、macOS和Windows上运行。
2. Downloading and Getting Started
2.下载并开始使用
First, let’s start by downloading the Arthas library either directly via the download link or using curl:
首先,让我们先通过下载链接或使用curl下载Arthas库。
curl -O https://alibaba.github.io/arthas/arthas-boot.jar
Now, let’s test that it’s working by running Arthas with the -h (help) option:
现在,让我们用-h(帮助)选项运行Arthas,以测试它是否工作。
java -jar arthas-boot.jar -h
If successful, we should see the help guide for all the commands displayed:
如果成功,我们应该看到显示的所有命令的帮助指南。
3. Case Study
3.案例研究
Throughout this tutorial, we’ll use a very simple application based on a fairly inefficient implementation of the Fibonacci sequence using recursion:
在本教程中,我们将使用一个非常简单的应用程序,它基于一个相当低效的Fibonacci序列的实现,使用递归。
public class FibonacciGenerator {
public static void main(String[] args) {
System.out.println("Press a key to continue");
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);
}
}
}
The most interesting part of this example is the fibonacci method that follows the mathematical definition of Fibonacci.
这个例子中最有趣的部分是斐波那契方法,它遵循斐波那契的数学定义。
In the main method, we use a for loop with relatively large numbers so our computer will be busy with longer computations. This is, of course, precisely what we want in order to demonstrate Arthas.
在main方法中,我们使用了一个for循环,数字相对较大,所以我们的计算机将忙于较长时间的计算。当然,这正是我们想要的,以便演示Arthas。
4. Starting Arthas
4.启动阿瑟斯
Now let’s try Arthas out! The first thing we need to do is run our small Fibonacci application. For that, we can use our favorite IDE or run it directly in the terminal. It will ask to press a key in order to start. We’ll press any key after we attach the process to Arthas.
现在让我们来试试Arthas吧!我们需要做的第一件事是运行我们的小型Fibonacci应用程序。为此,我们可以使用我们最喜欢的IDE或者直接在终端运行它。它将要求我们按一个键来启动。在我们将进程附加到Arthas之后,我们将按任何一个键。
Now, let’s run the Arthas executable:
现在,让我们运行Arthas可执行文件。
java -jar arthas-boot.jar
Arthas prompts a menu to select which process we want to attach to:
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
...
Let’s select the one with the name com.baeldung.arthas.FibonacciGenerator. Simply enter the number in the list, ‘1′ in this example, and then press Enter.
让我们选择名称为com.baeldung.arthas.FibonacciGenerator的那个。只需在列表中输入数字,本例中为’1’,然后按回车键。
Arthas will now attach to this process and start:
Arthas现在将依附于这个进程并开始。
INFO] Try to attach process 25500
[INFO] Attach process 25500 success.
...
Once we have Arthas started, we have a prompt where we can issue different commands.
一旦我们启动了Arthas,我们就有一个提示,在那里我们可以发布不同的命令。
We can use the help command to get more information about the available options. Moreover, in order to facilitate the use of Arthas, we can also use the tab key to autocomplete its commands.
我们可以使用help命令来获得更多关于可用选项的信息。此外,为了方便使用Arthas,我们还可以使用tab键来自动完成其命令。
After attaching Arthas to our process, now we can press a key and the program starts printing Fibonacci numbers.
在将Arthas附加到我们的进程之后,现在我们可以按一个键,程序就开始打印斐波那契数字。
5. Dashboard
5. 仪表板
Once Arthas is started, we can use the dashboard. In this case, we proceed by typing the dashboard command. Now we see a detailed screen with several panes and much information about our Java process:
一旦Arthas被启动,我们就可以使用仪表盘。在这种情况下,我们通过输入dashboard命令来进行。现在我们看到一个详细的屏幕,上面有几个窗格和许多关于我们的Java进程的信息。
Let’s take a look at some of these in more detail:
让我们更详细地看一下其中的一些情况。
- The top section is dedicated to the threads currently running
- One of the important columns is the CPU consumption for each thread
- Section 3 shows the CPU time per thread
- Another interesting pane is for memory analysis. Different memory regions are listed with their statistics. On the right-hand side, we have information about the Garbage Collector
- Finally, in section 5 we have information about the host platform and JVM
We can exit the dashboard by pressing q.
我们可以通过按q退出仪表板。
We should keep in mind that Arthas will be attached to our process even if we exit. So in order to properly unlink it from our process, we need to run the stop command.
我们应该记住,即使我们退出了,Arthas也会附着在我们的进程上。因此,为了正确地解除它与我们进程的联系,我们需要运行stop 命令。
6. Analyzing Stack Traces
6.分析堆栈痕迹
In the dashboard, we saw that our main process takes almost 100% of the CPU. This process has an ID of 1, which we can see in the very first column.
在仪表板上,我们看到我们的主进程几乎占用了100%的CPU。这个进程的ID是1,我们可以在第一栏看到。
Now that we’ve exited the dashboard, we can analyze the process in more detail by running the thread command:
现在我们已经退出了仪表板,我们可以通过运行thread命令来更详细地分析这个过程。
thread 1
The number passed as the argument is the thread id. Arthas prints out a stack trace that, unsurprisingly, is cluttered with calls to the fibonacci method.
作为参数传递的数字是线程ID。Arthas打印出了一个堆栈跟踪,毫不奇怪,它被对fibonacci方法的调用弄得很乱。
If the stack trace is long and tedious to read, the thread command allows us to use pipes:
如果堆栈跟踪很长,阅读起来很繁琐,线程命令允许我们使用管道。
thread 1 | grep 'main('
This will only print the line matching the grep command:
这将只打印与grep命令匹配的行。
[arthas@25500]$ thread 1 | grep 'main('
at com.baeldung.arthas.FibonacciGenerator.main(FibonacciGenerator.java:10)
7. Decompile a Java Class
7.反编译一个Java类
Let’s imagine a scenario where we’re analyzing a Java application that we know little or nothing about, and we suddenly discover that the stack is strewn with repetitive calls of the type:
让我们想象这样一个场景:我们正在分析一个我们知之甚少或一无所知的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)
...
Since we are running Arthas, we could decompile a class to see its content. To achieve that, we can use the jad command, passing the qualified class name as an argument:
由于我们正在运行Arthas,我们可以对一个类进行反编译以查看其内容。为了实现这一点,我们可以使用jad命令,将合格的类名作为参数。
jad com.baeldung.arthas.FibonacciGenerator
ClassLoader:
+-jdk.internal.loader.ClassLoaders$AppClassLoader@799f7e29
+-jdk.internal.loader.ClassLoaders$PlatformClassLoader@60f1dd34
Location:
/home/amoreno/work/baeldung/tutorials/libraries-3/target/
/*
* Decompiled with CFR.
*/
package com.baeldung.arthas;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
public class FibonacciGenerator {
public static void main(String[] arrstring) throws IOException {
The output is the decompiled Java class and some useful metadata like the location of the class. This is a really useful and powerful feature.
输出是反编译的Java类和一些有用的元数据,如类的位置。这是一个非常有用和强大的功能。
8. Search Class and Search Method
8.搜索类和搜索方法
The search class command comes in handy when searching for classes loaded in the JVM. We can use it by typing sc and passing a pattern, with or without wildcards, as an argument:
搜索类命令在搜索JVM中加载的类时很方便。我们可以通过输入sc并传递一个模式(无论是否有通配符)作为参数来使用它。
[arthas@70099]$ sc *Fibonacci*
com.baeldung.arthas.FibonacciGenerator
Affect(row-cnt:1) cost in 5 ms.
Once we have the qualified name for the class, we can then look for more information using two additional flags:
一旦我们有了类的限定名称,我们就可以使用两个额外的标志来寻找更多的信息。
- -d to display the details of the class
- -f to display the fields of the class
However, the fields of the class must be queried in conjunction with the details:
然而,该类的字段必须与细节一起查询。
[arthas@70099]$ sc -df com.baeldung.arthas.FibonacciGenerator
class-info com.baeldung.arthas.FibonacciGenerator
...
Likewise, we can use the command sm (search method) to look for loaded methods in a class. In this case, for our class com.baeldung.arthas.FibonacciGenerator, we can run:
同样地,我们可以使用命令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.
We could use the flag -d to retrieve the details of the methods as well. Finally, we can pass the name of the method an optional argument to narrow down the number of returned methods:
我们也可以使用标志-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. Monitoring Method Invocations
9.监测方法的调用
Another cool thing we can do with Arthas is to monitor a method. This can be very handy when debugging performance issues in our applications. For this, we can use the monitor command.
我们可以用Arthas做的另一件很酷的事情是监控一个方法。在调试我们的应用程序的性能问题时,这可能是非常方便的。为此,我们可以使用monitor命令。
The monitor command requires a flag -c <seconds> and two arguments — the qualified class name and the method name.
monitor命令需要一个标志-c <seconds>和两个参数–合格的类名和方法名。
For our case study, let’s now invoke monitor:
对于我们的案例研究,现在让我们调用monitor。
monitor -c 10 com.baeldung.arthas.FibonacciGenerator fibonacci
As expected, Arthas will print metrics about the fibonacci method every 10 seconds:
正如预期的那样,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%
...
We also have metrics for those calls that end up in failures — and these can be useful for debugging.
我们也有关于那些最终导致失败的调用的指标–这些对调试很有用。
10. Monitoring Method Arguments
10.监测方法论证
In case we need to debug the parameters of a method, we can use the watch command. But, the syntax is a bit more complex:
如果我们需要调试一个方法的参数,我们可以使用watch命令。但是,其语法要复杂一些。
watch com.baeldung.arthas.FibonacciGenerator fibonacci '{params[0], returnObj}' 'params[0]>10' -n 10
Let’s take a look at each of the arguments in detail:
让我们来详细看看每一个论点。
- The first argument is the class name
- The second is the method name
- The third argument is an OGNL expression defining what we want to watch — in this case, it’s the first (and only) method parameter, and the return value
- The fourth and final optional argument is a boolean expression used to filter the invocations we want to monitor
For this example, we only want to monitor the argument when it’s greater than 10. Finally, we add a flag to limit the number of results to 10:
在这个例子中,我们只想在参数大于10的时候监控它。最后,我们添加一个标志,将结果的数量限制在10个。
watch com.baeldung.arthas.FibonacciGenerator fibonacci '{params[0], returnObj}' 'params[0]>10' -n 10
Press Q or Ctrl+C to abort.
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],
]
...
Here, we can see examples of invocations with their CPU times and input/return values.
在这里,我们可以看到调用的例子及其CPU时间和输入/返回值。
11. Profiler
11.剖析器
A very visual capability for those interested in the performance of applications is available via the profiler command. The profiler will evaluate the performance of the CPU that our processes are using.
对于那些对应用程序的性能感兴趣的人来说,一种非常直观的能力可以通过profiler命令获得。剖析器将评估我们的进程所使用的CPU的性能。
Let’s run the profiler by launching profiler start. This is a non-blocking task, meaning we can continue using Arthas while the profiler is working.
让我们通过启动profiler start来运行分析器。这是一个非阻塞任务,意味着我们可以在剖析器工作的同时继续使用Arthas。
At any time, we can ask how many samples the profiler has by running profiler getSamples.
在任何时候,我们都可以通过运行profiler getSamples来询问分析器有多少样本。
Let’s now stop the profiler using profiler stop. At this point, a FlameGraph image is saved. In this precise case, we have a chart with the fibonacci thread dominating the graphic:
现在让我们使用profiler stop来停止剖析器。此时,一个FlameGraph图像被保存。在这个确切的案例中,我们有一个以斐波那契线为主导的图表。
Note that this chart can be particularly useful when we want to detect where our CPU time is being spent.
注意,当我们想检测我们的CPU时间花在哪里时,这个图表可能特别有用。
12. Conclusion
12.结语
In this tutorial, we have explored some of the most powerful and useful features of Arthas.
在本教程中,我们已经探索了Arthas的一些最强大和最有用的功能。
As we have seen, Arthas has many commands that can help us diagnose a variety of issues. It can also be particularly helpful when we cannot access the code of the application under scrutiny, or if we want to do a quick diagnostic of a problematic application running on a server.
正如我们所见,Arthas有许多命令可以帮助我们诊断各种问题。当我们不能访问被检查的应用程序的代码时,或者当我们想对一个在服务器上运行的有问题的应用程序进行快速诊断时,它也会特别有帮助。
As always, the full source code of the article is available over on GitHub.
一如既往,文章的完整源代码可在GitHub上获得over。