转载

Java 诊断利器 Arthas 优雅排查生产环境

Java 诊断利器 Arthas 优雅排查生产环境

前言

Arthas 是Alibaba开源的Java诊断工具。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。对分秒必争的线上异常, Arthas 可帮助我们快速诊断相关问题。

下载安装

下载 Arthasarthas-boot.jar

下载 arthas 之后,先来了解帮助信息,可以通过 java-jar arthas-boot.jar-h 命令查看,这里给出了一些例子和参数说明

启动

启动 arthas 之前,先启动一个 springboot 的应用。该 demo 在地址 https://github.com/yangtao9502/ytao-springboot-demo

启动 arthas-boot.jar 命令

这里注意需要启动 demoarthas 使用同一权限用户,否则使用attach机制获取不到进程信息(这里刚使用时没注意,遇到过这个问题)。例: root 用户启动 demou1 用户启动 arthas 时,打印信息 Cannotfind java process.Trytopass<pid>incommand line. Java 诊断利器 Arthas 优雅排查生产环境

查看源码,在获取进程之后,添加日志输出。结果为空,返回 -1 ,判断结果小于 0 时,直接退出。 Java 诊断利器 Arthas 优雅排查生产环境

启动类 Bootstrap#main 的代码 Java 诊断利器 Arthas 优雅排查生产环境

进程工具类 ProcessUtils#select 的代码 Java 诊断利器 Arthas 优雅排查生产环境

通过上面也分析到,我们启动 arthas 之前,必须要先启动我们的目标进程,否则 arthas 可能无法启动。

使用 root 用户启动成功界面 Java 诊断利器 Arthas 优雅排查生产环境

选择java进程,这里我们的 ytao-springboot-demo 是 1,选择后会有连接信息

dashboard 数据面板

使用 dashboard 命令,可以查看线程,内存,GC,以及Runtime信息 Java 诊断利器 Arthas 优雅排查生产环境

jad 反编译

有时我们会遇到线上代码运行结果不是我们期望的结果,有种情况就是线上代码不是我们想要的版本,但是要查看的话,需要下载后再进行反编译。这时 arthasjad 可以帮助我们线上进行即时反编译,确认代码是否符合我们的版本。

Java 诊断利器 Arthas 优雅排查生产环境

watch 函数执行信息

使用 watch 命令可以查看函数的执行信息。 watch 的参数列表(来自官网)

参数 参数说明
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
express 观察表达式
condition-express 条件表达式
[b] 在方法调用之前观察
[e] 在方法异常之后观察
[s] 在方法返回之后观察
[f] 在方法结束之后(正常返回和异常返回)观察
[E] 开启正则表达式匹配,默认为通配符匹配
[x:] 指定输出结果的属性遍历深度,默认为 1

当我们遇到线上数据 bug 时,我们一般处理的手段就是开发环境模拟线上数据,从生产日志中查找线索,再或者远程 debug 。以上不管哪种排查手段,相对都是比较麻烦。这时Arthas的 watch 可以帮助我们查看实时的代码执行情况。使用观察表达式可以查看函数的 参数 , 返回值 , 异常信息 。观察表达式主要由 OGNL 表达式组成,所以可以编写 OGNL 表达式来执行。

观察表达式的变量

变量 变量说明
params 函数的入参
returnObj 函数的返回值
throwExp 异常信息
target 当前对象

查看一个函数的入参和返回值

Java 诊断利器 Arthas 优雅排查生产环境

打印信息 isEmpty=false;size=1 可以看到参数为非空,参数数量为一个。查看具体入参信息

Java 诊断利器 Arthas 优雅排查生产环境

查看异常信息

当我们传入一个参数为 -1 时,打印出我们定义的非法参数异常 Java 诊断利器 Arthas 优雅排查生产环境

watch 除了观察表达式外,还能使用 条件表达式 ,以及 观察事件点注意 使用观察事件点时,有些观察表达式的变量不一定存在,比如使用 -b 时,返回值和异常信息都为空。 Java 诊断利器 Arthas 优雅排查生产环境

有时我们排查某个函数,不能马上获取到函数的信息, arthas 给提供的 后台异步任务 可以帮助我们记录日志。使用方式和Linux的类似。

查看异步保存的日志 Java 诊断利器 Arthas 优雅排查生产环境

tt 定位异常调用

上面所介绍的 watch 可以排查函数的调用情况,比较适用在已知当次调用可能存在的情况后,查看信息。如果一个函数调用n次后,有几次为执行异常,我们要去找出这些异常的调用,在 watch 中排查就不怎么方便了。使用 tt 命令可以较方便查看异常的调用及信息。对 com.ytao.service.UserServiceImpl#getUser 的函数查看, -t 是每次调用该函数都会记录

记录信息 Java 诊断利器 Arthas 优雅排查生产环境

查看所有记录

查看指定函数记录

输出信息说明

表格字段 字段解释
INDEX 时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。
TIMESTAMP 方法执行的本机时间,记录了这个时间片段所发生的本机时间
COST(ms) 方法执行的耗时
IS-RET 方法是否以正常返回的形式结束
IS-EXP 方法是否以抛异常的形式结束
OBJECT 执行对象的hashCode(),注意,曾经有人误认为是对象在JVM中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体
CLASS 执行的类名
METHOD 执行的方法名

从上面参数中我们看到 1003 调用是以抛异常的形式结束,因为 tt 会记录每次调用的信息,所以我们可以查看 1003 的详细信息

Java 诊断利器 Arthas 优雅排查生产环境

trace 查看调用链路

我们常会遇到调用某个api时rt过长,我们就要找出调用链上的某个或几个函数进行优化,我们通常定位几个可能的锚点,打印各个锚点间的rt。或者从日志中找出日志打印的时间点计算出时间差,不管使用哪种方法都比较繁琐。当使用 arthastrace 命令可以轻松的完成我们的需求。 trace 参数说明

参数 参数说明
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
condition-express 条件表达式
[E] 开启正则表达式匹配,默认为通配符匹配
[n:] 命令执行次数
#cost 方法执行耗时

使用 trace 输出 com.ytao.controller.UserController#getUser 的信息

输出结果

在实际使用使用排查过程中,为了减少无用信息的输出,我们一般会使用 #cost 过滤耗时不长和jdk自带的函数,可以忽略的调用,减少信息的输出。例如:过滤掉小于 1ms 的调用

redefine 实现热部署

当我们查找出bug,想要快速上线拯救苍生的时候, Arthas 为我们准备了 redefine 命令来实现热更新。尽管现在都在倡导 jad / mc / redefine热更 一条龙,但是线上代码建议本地编译好后再进行替换,避免手误操作。首先先在 UserServiceImpl 中添加一行代码 Java 诊断利器 Arthas 优雅排查生产环境

获取 classLoaderHash ,通过 sc 命令获取类的信息

Java 诊断利器 Arthas 优雅排查生产环境

执行 redefine 修改的类

通过打印的信息验证是否更新 UserServiceImpl

Arthas 的使用,除了上文中所讲解到的,还有一些其他的诊断功能,这只是我个人使用的方法。但是使用该类工具一定要有套组合拳,对排查问题过程中,遇到问题有对应的排查手段,并非盲目排查。

原文  https://mp.weixin.qq.com/s/Qb0jGy6xhNqN5CFIGFfKNQ
正文到此结束
Loading...