Java诊断利器 Arthas-- 一款释放潜力的神器

嘿,你是不是对Java开发中的调试和诊断问题感到头疼?

别担心,我要告诉你一个秘密武器!它就像是一位超级英雄,能够释放你的潜力,解决你的烦恼!它的名字叫做Arthas,是一款Java诊断利器,简直就是开发者的救星!

它不仅能够帮助你实时监控和分析Java应用程序的运行状态,还能让你在生产环境中进行线上调试,简直就是神一般的存在!不管是查看方法调用堆栈、监控线程状态,还是动态修改代码,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 RUNNABLEat 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.FibonacciGeneratorclass-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 fibonaccideclaring-class  com.baeldung.arthas.FibonacciGeneratormethod-name      fibonaccimodifier         public,staticannotationparameters       intreturn           longexceptionsclassLoaderHash  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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/6733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手写Nacos基本原理——服务注册 配置管理

手写Nacos基本原理 一、背景介绍二、 思路方案三、过程nacosService代码pom文件配置文件具体类 nacosSDK代码pom文件配置类具体类 serviceA代码pom文件配置文件具体类 serviceB代码pom文件配置文件具体类 实现效果四、总结五、升华 一、背景介绍 之前在项目开发的过程中&#…

C# List 详解五

目录 26.GetType() 27.IndexOf(T) 28.IndexOf(T, Int32) 29.IndexOf(T, Int32, Int32) 30.Insert(Int32, T) 31.InsertRange(Int32, IEnumerable) 32.LastIndexOf(T) 33.LastIndexOf(T, Int32) 34.LastIndexOf(T, Int32, Int32) …

【CAS6.6源码解析】调试Rest API接口

CAS的web层默认是基于webflow实现的&#xff0c;ui和后端是耦合在一起的&#xff0c;做前后端分离调用和调试的时候不太方便。但是好在CAS已经添加了支持Rest API的support模块&#xff0c;添加相应模块即可。 文章目录 添加依赖并重新build效果 添加依赖并重新build 具体添加…

32位Cortex-M4 MCU:LPC54607J256ET180E、LPC54605J512BD100K 180MHz嵌入式微控制器

LPC546xx 32 位微控制器(MCU) 具有丰富的外设集、极低的功耗和增强的调试功能。 LPC546xx MCU系列采用ARM Cortex-M4内核&#xff0c;可提供以太网支持&#xff0c;并设有一个TFT LCD控制器和两个CAN FD模块。LPC546xx MCU旨在提高灵活性和性能可扩展性&#xff0c;可提供高达1…

Vue3 Vite electron 开发桌面程序

Electron是一个跨平台的桌面应用程序开发框架&#xff0c;它允许开发人员使用Web技术&#xff08;如HTML、CSS和JavaScript&#xff09;构建桌面应用程序&#xff0c;这些应用程序可以在Windows、macOS和Linux等操作系统上运行。 Electron的核心是Chromium浏览器内核和Node.js…

ABAP 为N的一个数,在原来基础上浮动在-30~30

需求&#xff1a;为N的一个数&#xff0c;在原来基础上浮动在-30~30 *&---------------------------------------------------------------------* *& Report ZZZZ111 *&---------------------------------------------------------------------* *& 需求&…

【算法基础:搜索与图论】3.4 求最短路算法(Dijkstrabellman-fordspfaFloyd)

文章目录 求最短路算法总览Dijkstra朴素 Dijkstra 算法&#xff08;⭐原理讲解&#xff01;⭐重要&#xff01;&#xff09;&#xff08;用于稠密图&#xff09;例题&#xff1a;849. Dijkstra求最短路 I代码1——使用邻接表代码2——使用邻接矩阵 补充&#xff1a;稠密图和稀疏…

npm i babel-plugin-import -D之后报错

替换modules/.bin/XX文件 1.vue-cli-service #!/bin/sh basedir$(dirname "$(echo "$0" | sed -e s,\\,/,g)")case uname in*CYGWIN*) basedircygpath -w "$basedir";; esacif [ -x "$basedir/node" ]; then"$basedir/node"…

【NLP】视觉变压器与卷积神经网络

一、说明 本篇是 变压器因其计算效率和可扩展性而成为NLP的首选模型。在计算机视觉中&#xff0c;卷积神经网络&#xff08;CNN&#xff09;架构仍然占主导地位&#xff0c;但一些研究人员已经尝试将CNN与自我注意相结合。作者尝试将标准变压器直接应用于图像&#xff0c;发现在…

CAXA中.exb或者.dwg文件保存为PDF

通常CAXAZ中的文件为.exb或者.dwg格式&#xff0c;我们想打印或者保存为PDF文件格式&#xff0c;那么就用一下的方法&#xff1a; CAXA文件如图所示&#xff1a; 框选出你要打印的图纸&#xff01;&#xff01;&#xff01;&#xff01; 我们选择"菜单"->"…

【算法基础:搜索与图论】3.5 求最小生成树算法(PrimKruskal)

文章目录 最小生成树介绍朴素Prim算法算法思路⭐例题&#xff1a;858. Prim算法求最小生成树 Kruskal算法算法思路⭐例题&#xff1a;859. Kruskal算法求最小生成树 最小生成树介绍 最小生成树 有关树的定义 生成子图&#xff1a;生成子图是从原图中选取部分节点以及这些节点…

Keepalived热备、Keepalived+LVS、HAProxy监控及后端服务器健康检查、负载均衡调度器对比

day02 day02KeepAlived高可用集群配置高可用的web集群监控本机80端口&#xff0c;实现主备切换实现原理实施配置高可用、负载均衡的web集群配置高可用、负载均衡HAProxy配置haproxy负载均衡调度器比较LVS&#xff08;Linux Virtual Server&#xff09;NginxHAProxy KeepAlive…

Pytorch个人学习记录总结 08

目录 神经网络-搭建小实战和Sequential的使用 版本1——未用Sequential 版本2——用Sequential 神经网络-搭建小实战和Sequential的使用 torch.nn.Sequential的官方文档地址&#xff0c;模块将按照它们在构造函数中传递的顺序添加。代码实现的是下图&#xff1a; 版本1—…

16_LinuxLCD驱动

目录 Framebuffer设备 LCD驱动简析 LCD驱动程序编写 LCD屏幕参数节点信息修改 LCD 屏幕背光节点信息 使能Linux logo显示 设置LCD作为终端控制台 Framebuffer设备 先来回顾一下裸机的时候LCD驱动是怎么编写的,裸机LCD驱动编写流程如下: 1.初始化I.MX6U的eLCDIF控制器,…

Jenkins发送的邮箱中没有带配置的压缩附件

【问题描述】&#xff1a;Jenkins中明明配置了邮箱发送时要带压缩附件&#xff0c;收到的邮箱中却没有附件内容 【问题定位】&#xff1a;压缩附件没有放在Jenkins工作空间下&#xff0c;所以发送的邮件并未发送附件 【解决办法】&#xff1a; 1&#xff09;把压缩附件放到J…

kubernetes持久化存储卷

kubernetes持久化存储卷 kubernetes持久化存储卷一、存储卷介绍二、存储卷的分类三、存储卷的选择四、本地存储卷之emptyDir五、本地存储卷之 hostPath六、网络存储卷之nfs七、PV(持久存储卷)与PVC(持久存储卷声明)7.1 认识pv与pvc7.2 pv与pvc之间的关系7.3 实现nfs类型pv与pvc…

Spring MVC拦截器和跨域请求

一、拦截器简介 SpringMVC的拦截器&#xff08;Interceptor&#xff09;也是AOP思想的一种实现方式。它与Servlet的过滤器&#xff08;Filter&#xff09;功能类似&#xff0c;主要用于拦截用户的请求并做相应的处理&#xff0c;通常应用在权限验证、记录请求信息的日志、判断用…

EfficientNetV2: Smaller Models and Faster Training

EfficientNetV2: Smaller Models and Faster Training 1.Abstract 本文提出了一种训练速度快、参数量少、模型小的卷积神经网络EfficientNetV2。 训练采用了NAS感知技术与缩放技术对训练速度与参数数量进行联合优化。 NAS感知技术&#xff1a; 全名是神经架构搜索&#xff0…

quartus工具篇——ROM ip核

quartus工具篇——ROM ip核 1、ROM简介 FPGA中的ROM(Read-Only Memory)是一种只读存储器,主要用来存储固化的初始化配置数据。FPGA ROM的特性主要有: 预编程初始化 - ROM在FPGA编程时就已经写入了初始值,这些值在整个工作周期保持不变。初始化配置 - ROM通常用来存储FPGA的初…

Flutter的开发环境搭建-图解

前言&#xff1a;Flutter作为一个移动应用开发框架&#xff0c;具有许多优点和一些局限性。最大的优点就是-跨平台开发&#xff1a;Flutter可以在iOS和Android等多个平台上进行跨平台开发&#xff0c;使用一套代码编写应用程序&#xff0c;节省开发时间和成本。 Flutter可以编…