java 时间差_Java诊断利器Arthas优雅排查生产环境

来源公众号ytao ,

作者ytao

前言

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

下载安装

下载 Arthas的 arthas-boot.jar

wget https://alibaba.github.io/arthas/arthas-boot.jar

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

04af8dad444ff5d3840a7b2f25b00896.png
99c001cfcd8e3b4ec37935c2d9ae34b9.png

启动

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

java -jar ytao-springboot-demo.jar

启动 arthas-boot.jar命令

java -jar arthas-boot.jar

这里注意需要启动 demo和 arthas使用同一权限用户,否则使用attach机制获取不到进程信息(这里刚使用时没注意,遇到过这个问题)。例:root用户启动 demo, u1用户启动 arthas时,打印信息 Cannotfind java process.Trytopassincommand line.

80c57a7c7e1b63f1aa0f2abfb56379e4.png

查看源码,在获取进程之后,添加日志输出。结果为空,返回 -1,判断结果小于 0时,直接退出。

87da41a35ea2474f33ede4679b67489d.png

启动类 Bootstrap#main的代码

068d71f4e7c2f2a283568801e3664e30.png

进程工具类 ProcessUtils#select的代码

5a750876770de76a77bcf4d154bef17b.png

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

使用 root用户启动成功界面

724b31bab2c034fe0bfbf34c0116bd8c.png

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

1476d9d3fd35fa26a821be01cf307bda.png

dashboard 数据面板

使用 dashboard命令,可以查看线程,内存,GC,以及Runtime信息

ef75e656025316749bbd7876048ad10b.png

jad 反编译

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

jad com.ytao.service.UserServiceImpl

758b039db43ed63a545add96f5280f84.png

watch 函数执行信息

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

a808da4207889a4aff73fce1e297ccc8.png

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

观察表达式的变量

82d78354c74efc5af8838ede45b191a9.png

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

watch com.ytao.service.UserServiceImpl getUser "{params,returnObj}"

28f59a31438ba091d623d521fb7a5404.png

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

watch com.ytao.service.UserServiceImpl getUser "{params[0],returnObj}"

c9960863f7182660ca73db43dbb7b821.png

查看异常信息

watch com.ytao.service.UserServiceImpl getUser "throwExp"

当我们传入一个参数为 -1时,打印出我们定义的非法参数异常

23b7c81af56b6ce8941a394c5a4dcaae.png

watch除了观察表达式外,还能使用 条件表达式,以及 观察事件点。注意使用观察事件点时,有些观察表达式的变量不一定存在,比如使用 -b时,返回值和异常信息都为空。

aa5d64c6af5436613e25de5fce0f7707.png

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

watch com.ytao.service.UserServiceImpl getUser "{params,returnObj}" > /log/w.log &

查看异步保存的日志

c8e5126e679ca0dea36f3dfcc4f5dbd7.png

tt 定位异常调用

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

tt -t com.ytao.service.UserServiceImpl getUser

记录信息

57e78d6862e920f43335fc7d62db4086.png

查看所有记录

tt -l

查看指定函数记录

tt -s 'method.name=="getUser"'

输出信息说明

6e5edbe001436800ba06a94dfe8f15e5.png

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

tt -i 1003

8b87f1b564122fe0fbc4fc9daba58ce6.png

trace 查看调用链路

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

7cee1247b3bb1ac3577fec36356b4f48.png

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

trace com.ytao.service.UserServiceImpl getUser

输出结果

07a8481bfdf644dee8c8d70d117210a6.png

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

trace com.ytao.service.UserServiceImpl getUser '#cost > 1'

redefine 实现热部署

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

d0f5923fb96739d21e063771369f64ab.png

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

sc -d *UserServiceImpl

10aff1cd0592e5620109867cb35d5bcc.png

执行 redefine修改的类

redefine -c 1d56ce6a /usr/local/jar/UserServiceImpl.class

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

2ac724bd30ac63c8229c3fc08c9e40c0.png

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值