在公司定位故障问题的时候,一般我们会采用在代码中关键代码中打印日志,然后采用在环境容器内换 Jar 包的形式进行问题定位分析。但是这样定位的问题流程很麻烦:
- 首先你要确保你打印日志的全面性,万一某个关键信息没有打印出来你就需要重新打印、换包、重启服务,一套流程下来浪费很多时间;
- 其次不是所有环境都运行换包和重启服务
所以最近我一直在找更好的故障问题定位方法,然后我发现阿里开源的 Java 服务诊断工具好像还不错,它可以查看方法调用入参、返回值,被调用的调用路径、调用耗时、方法调用次数、成功次数、失败次数等这些都可以记录,所以学习记录一下这个工具。
什么是 arthas#
官方介绍:
Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
运行环境#
- 只支持 JDK 6 + 的环境
- 由 Java 编写的,支持跨平台:支持 Linux(主要)、Mac、Windows
特性#
- 采用命令行交互模式
- 提供
Tab
键自动补全的功能
初步使用#
因为平时公司使用的环境主要是在容器中,所以以下就主要记录在 Linux 环境下如何使用这个工具
下载使用包#
由于公司环境是内网环境,不支持直接访问连接 Github 进行安装包的下载,这里防止机器的网络问题无法下载,所以采用的是手动先从 Github 下载拷贝到服务容器内部的方式进行使用
在 Github 中下载完整的安装包,下载地址 :https://github.com/alibaba/arthas/releases
容器环境下解压#
卸载#
定位完问题之后也要打扫好战场,那卸载这个工具的方法也记录一下
执行完以下三步即可卸载工具
运行#
首先启动一个不会停止的 Java 程序服务,官方的安装包下就附带了一个给我们练手的 Jar 包:
math-game.jar
(不过一般我们的服务也是一直运行的,这里就使用官方的包作为记录)
然后再启动 arthas
常用命令#
help#
dashboard#
仪表板:显示当前系统的实时数据面板,平时没有这个 dashboard 的时候我们一般只能通过 Linux 自带的
top
命令查看系统运行的信息
输入 dashboard,按 回车/enter
,会展示当前进程的信息,按 ctrl+c
或输入 q
可以中断执行。
显示的信息大概分为 3 大块:
- 最上面的是线程相关信息
- 中间区域是 JVM 内存相关的信息
- 最下面的是 Java 的运行环境信息
具体每一列的信息可以参考官方文档
thread#
查看当前线程信息堆栈
当没有参数时,显示第一页线程的信息#
默认按照 CPU 增量时间降序排列,只显示第一页数据。
支持一键展示当前最忙的前 N 个线程并打印堆栈#
thread --all, 显示所有匹配的线程#
thread id, 显示指定线程的运行堆栈#
thread -b, 找出当前阻塞其他线程的线程#
watch#
观察指定方法的调用情况
可以观察到:
方法返回值、入参、方法抛出的异常,还可以通过编写 OGNL 表达式进行对应变量的查看
观察函数调用返回时的参数、this 对象和返回值#
同时观察函数调用前和函数返回后#
观察当前对象中的属性#
如果想查看函数运行前后,当前对象中的属性,可以使用 target 关键字,target 代表当前对象,然后使用 target.field_name 访问当前对象的某个属性
trace#
方法内部调用路径,并输出路径上的每个节点上耗时,服务间调用时间过长时使用
- 输出结果中 #24 表示 在源文件的第 24 行调用了
primeFactors()
函数 - 输出结果中 #25 表示 在源文件的第 25 行调用了
print()
函数
stack#
输出当前方法被调用的调用路径,当我们需要知道这个方法(被很多地方调用过)从那里开始执行了就可以使用这个命令(适合寻根溯源)
jad#
反编译指定已加载类的源码,便于在线上理解业务逻辑,反编译出来的代码是带语法高亮的