阿里开源故障诊断工具Arthas(阿尔萨斯)
一、简介
Arthas 是Alibaba于2018 年9月开源的Java诊断工具,深受开发者喜爱。当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
Github:https://github.com/alibaba/arthas
文档:https://alibaba.github.io/arthas/
二、Demo示例(微服务功能延时优化)
现有一个微服务项目,某一个服务访问时间很长,生产时间最长已经到10s,忍无可忍
现在需要优化,正常情况,我们开发人员需要一次次的需要现场人员替换class,通过控制台一点点打印出问题所在,现在我们通过arthas什么也不需要替换。
2.1 查找对应的服务
[root@localhost arthas]# ps -ef|grep java
通过命令查找队形的后台服务,找到对应的action、controller或者implement类
2.2 启动arthas
arthas是一个独立的jar包,基于springboot创建,只需要在生产服务器放置一个jar包,需要的时候启动排查,不需要的时候关闭(安全检查减少不必要的风险)。
通过java –jar启动,进入控制台,arthas可以远程,也可以通过浏览器查看。
[root@localhost arthas]# java -jar arthas-boot.jar 4064
2.3 trace观察耗时
trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
通过命令监测直接看出是JPAutil耗时比较长,开发人员基本就可以看出JPAutil是数据库dao层操作,接下来,我们希望能看到sql语句是什么。
2.4 watch查看输入/输出/耗时
Watch命令观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。
通过watch命令过滤相关sql语句,发现前三个sql语句耗时1.7s 、1.7s 、1.8s进行sql优化即可。
三、快速入门
3.1 启动arthas
Arthas由springboot项目构建,包名为arthas-boot.jar,可以通过java –jar进行启动
3.2 查看dashboard
输入dashboard,按回车/enter,会展示当前进程的信息,按ctrl+c可以中断执行。
3.3 通过sc命令获取类信息
查找某一个类所属的jar包,可以用于class冲突时,查找是哪个jar包里的class生效。
查看某一个路径下,jvm加载的所有类:
3.4 通过thread命令来获取到进程
thread 1会打印线程ID 1的栈,通常是main函数的线程。
$ thread 1
指定最忙的前N个线程并打印堆栈
$ thread -n 3
找出当前阻塞其他线程的线程
$ thread -b
3.5 通过jad来反编译Class
通过在生产服务器直接反编译jvm中的class文件,查看是否是我们编写的有效文件
3.6 通过watch查看方法输入输出
通过watch命令来查看某一类中,某一方法的输入、输出值,无效通过开发人员频发替换class就可以定位问题。
3.7 退出arthas
如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出arthas,可以执行stop命令。
四、arthas命令介绍
4.1 linux常见命令
查看进程ps -ef|grep java
查看内存使用情况
# free
查看各应用内存占用情况
# ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'
rsz为内存占用情况,单位KB
或者
# top
或者
top -H -p pid
4.2 启动命令java –jar
解压后,在文件夹里有arthas-boot.jar,直接用java -jar的方式启动:
java -jar arthas-boot.jar
或者 java -jar arthas-boot.jar 进程id
# java -jar arthas-boot.jar 2986
打印帮助信息:
java -jar arthas-boot.jar -h
进入arthas后
4.3 实时数据面板命令dashboard
输入dashboard,会展示当前进程的信息
$ dashboard
4.4 线程命令thread
打印线程ID 1的栈
$ thread 1
指定最忙的前N个线程并打印堆栈
$ thread -n 3
找出当前阻塞其他线程的线程
$ thread -b
4.5 反编译命令jad
反编译
$ jad com.demo.cloud.mservice.audit.AuditTask
4.6 类搜索命令sc
获取类是哪个包加载的
sc -d com.demo.ywsdService_YW.app.service.yw.impl.*
$ sc -d com.squareup.okhttp.OkHttpClient.*
4.7 方法监测命令watch
监测返回值watch -x 3表示深度
$ watch com.demo.ywsdServiceApp.adapter.rest.account.LoginContreller wxUserLogin "{params,returnObj}" -x 3
$ watch com.demo.ywsdServiceApp.adapter.rest.account.LoginContreller wxUserLogin "{params,target,returnObj}" -x 3
根据条件去查语句
$ watch com.demo.cloud.jpa.util.JPAUtil executeNativeQuery "{params,returnObj}" "params[0].indexOf ('base_monitoring_point')>-1" -x 3
4.8方法链路跟踪及耗时命令trace
监测方法耗时 -n 1 表示监测1次
$ trace com.demo.ywsdServiceApp.app.service.account.impl.DemoApplImpl appGetxqsbInfor -n 1
$ trace com.demo.ywsdServiceApp.app.service.account.impl.DemoAppYngllImpl getYnOverview -n 1
$ trace com.demo.ywsdService_YW.app.service.yw.impl.GdcServiceImpl getYnOverview -n 1
查看哪个filter生效
$ trace javax.servlet.Filter *
4.9监控方法调用命令monitor
方法执行监控
monitor -c 5 com.demo.ywsdServiceApp.app.service.account.impl.DemoAppYngllImpl getYnOverview
4.10查看jvm属性命令sysprop
查看当前JVM的系统属性
$ sysprop
修改单个属性
$ sysprop user.country
$ sysprop user.country CN
4.11查看日志配置信息命令logger
查看logger信息,更新logger level
$ logger
查看指定名字的logger信息
$ logger -n console
更新logger level
$ logger --name ROOT --level debug
4.12 远程窗口arthas-tunnel-server
webconsole远程端口号3658
http://127.0.0.1:3658/
http://172.20.32.54:3658/
默认情况下,arthas只listen 127.0.0.1,所以如果想从远程连接,则可以使用 --target-ip参数指定listen的IP
注意防火墙
# vi /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3658 -j ACCEPT
# service iptables restart
java -jar arthas-tunnel-server-3.1.7.jar --target-ip 172.20.32.54
4.13火焰图命令profiler
生成应用热点的火焰图
$ profiler start
$ profiler stop
默认火焰图svg格式,需要html
$ profiler stop --format html
4.13退出命令stop
如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出arthas,可以执行stop/shutdown命令
退出
$ stop