作者 | 张奇(司楚)
当线上碰到头疼的问题时,还在对着代码一行行的看?真的不太时髦了啊喂~
俗话说的好 “问题排查不用愁,Arthas 来帮您忙。” 今天就来说说这个让妈妈再也不用担心我排查问题的 Java 诊断神器:Arthas!
什么是 Arthas?
Arthas 是一款开源在线诊断工具,采用命令行交互模式,支持 web 端在线诊断,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。相对比直接下载使用,我推荐开发者可以试一下通过 IDE插件 Cloud Toolkit 中使用Arthas 来实现一键远程诊断功能。
得益于 Arthas 强大且丰富的功能,让 Arthas 能做的事情超乎想象。下面仅仅列举几项常见的使用情况,更多的使用场景可以在熟悉了 Arthas 之后自行探索。
Arthas 的原理、命令在其官方文档有详细介绍,下文将介绍一下近期几个使用场景。
平时服务器请求都很正常。压测时,依赖的服务、数据库也都没有到达瓶颈,但是机器的 CPU 全部飘红,why?
通过 jstack 命令,只能看到某一时刻的堆栈,没有抓到真凶。
thread 查看当前线程信息,查看线程的堆栈。 thread -n 3 -i 10000 可以统计 10 秒内最忙的 3 个线程,并且打印它们的堆栈,很容易发现问题。最终发现的问题比较简单:日志中打印了 location 的信息,包括 类名、方法名和行号。 动态获取代码的方法名、行号等信息,通常是通过 new Throwable() -> 打印 Throwable 的堆栈 -> 截取堆栈中最顶层的业务代码 -> 拆分字符串获取类、方法、行号等信息, 打印堆栈对性能损耗是比较大的。
有段时间,总是碰到几次偶尔的超时,但是看日志都正常,鹰眼的调用链路都完全 ok,没有哪一步数据库操作或者 HSF 调用是特别慢的。
各种监控统计的时间维度的耗时,都十分正常,无法找到那个 rt 的尖刺。
想到了可能是日志的问题,但是没有证据支撑。
trace 命令能监控每一步的耗时,并且可以配合条件表达式,当耗时超过 xx ms 时打印详细日志。
找台机器,输入命令,后面的就是静等了。再次出现 rt 尖刺时,能够捕捉到耗时的分布情况。
通过 Arthas 拿到的结果,定位到是日志打印的问题。同步日志改为异步日志后,问题解决。
之前碰到过一个 json 序列化时输出的数字带不带引号的问题。当时各种 debug、看代码,发现是通过 ASM 动态字节码的方式生成的序列化类。到这完全放弃了,debug 已经无法定位问题了。当时通过另外一种方式避免了这种问题。
反过来看这个问题的时候,我们可以通过 Arthas 的 jad 命令,反编译动态字节码生成的类,结合 watch 等命令,定位排查问题。
jad——反编译指定已加载类的源码
还有什么?
有了这些能力就算万能了?不不,接着往下看。
在问题排查过程中,发现了日志输出到了控制台,这个对性能的损耗是比较大的。有什么办法,在不发布的情况下紧急解决它?
sc -d ch.qos.logback.core.ConsoleAppender
class-info ch.qos.logback.core.ConsoleAppender
code-source /home/admin/.../lib/logback-core-1.2.3.jar
name ch.qos.logback.core.ConsoleAppender
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name ConsoleAppender
modifier public
annotation
interfaces
super-class +-ch.qos.logback.core.OutputStreamAppender
+-ch.qos.logback.core.UnsynchronizedAppenderBase
+-ch.qos.logback.core.spi.ContextAwareBase
+-java.lang.Object
class-loader +-com.taobao..LaunchedURLClassLoader@58dad04a
+-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@58ceff1
classLoaderHash 5f205aa
ognl -c 5f205aa '@org.slf4j.LoggerFactory@getLogger("root").aai.appenderList'
1ognl -c 5f205aa
'@org.slf4j.LoggerFactory@getLogger("root").aai.appenderList.remove(0)'
排查性能问题的时候,还有一个神器:火焰图通过火焰图,很清晰的看到一段时间内,对每个方法耗时的统计。
方式一:通过Cloud Toolkit 实现 Arthas 一键远程诊断
Cloud Toolkit 是阿里云发布的免费本地 IDE 插件,帮助开发者更高效地开发、测试、诊断并部署应用。通过插件,可以将本地应用一键部署到任意服务器,甚至云端(ECS、EDAS、ACK、ACR 和 小程序云等);并且还内置了 Arthas 诊断、Dubbo工具、Terminal 终端、文件上传、函数计算 和 MySQL 执行器等工具。不仅仅有 IntelliJ IDEA 主流版本,还有 Eclipse、Pycharm、Maven 等其他版本。
推荐使用 IDEA 插件下载 Cloud Toolkit 来使用 Arthas:
http://t.tb.cn/2A5CbHWveOXzI7sFakaCw8
方式二:直接下载
地址:https://github.com/alibaba/arthas