uit我们简单设想下一个场景 线上系统突然卡顿 查看pinponint发现 有gc情况频繁出现 慢线程数也在上涨
这时候的第一反应 是先去看下日志 观察了日志也没有发现 什么明显的报错日志 而开发在遇到这种情况也比较懵 不管啥 先把dump文件给他 然后就是等待他的后续分析了 结果就是暂时重启先解决问题 然后后面就没有然后了 你忙着去解决其它问题了 开发忙着去写下一个bug了 hhh
上述场景 在运维工程师的工作中 绝对是经常发生的 java问题的排查 涉及到的逻辑比较复杂 设计的命令的也比较多 jmap jstack jhat jstat等等 dump下来的文件 也需要和开发配合一起查看 所以有没有一个 更加高效的排查方式 能够快速的定位到问题呢
前段时间接触到的 一个阿里开源的工具 Arthas 这款工具可以做啥呢 可以从全局的角度来观察系统的运行情况 最方便的就是 它无需重启服务 随装随用 它的命令行模式 也贴合运维的实际工作场景 而且支持tab补全功能 这个工具不仅是运维排查问题的利器 也是开发过程中会使用到的利器
上述呢主要介绍了一下 这款工具可以干嘛 下面我们具体介绍下 这款工具应该如何使用 全文干货 可以收藏慢慢看
一、如何使用?
1.安装及测试程序运行
这款工具的安装也是很简单的
#github直接安装wget https://alibaba.github.io/arthas/arthas-boot.jar#如果你要测试的话 可以运行一个简单的java程序wget https://arthas.aliyun.com/arthas-demo.jarjava -jar arthas-demo.jar
如上的arthas-demo.jar包 运行过程中可以随机生成整数 然后进行因式分解
2.运行工具 并选择需要分析的java程序
然后我们通过java -jar arthas-boot.jar 运行分析工具
当你看到有如下的界面的时候 就代表运行成功了 可以继续分析了
可以通过输入help来查看更多的命令
3.具体介绍几个用到比较多的命令
dashboard
和你想的一样 这个命令会打印一个实时的系统监控图表 通过Q可以退出 具体如下图
thead
这个命令可以指定具体的 线程ID 例如thread 1
还支持管道符 如 thread 1 |grep 'main' 具体如下
sc
这个命令可以查找 JVM里面已经加载的类
jad
这个命令厉害了 可以直接反编译出源代码
watch
这个命令可以查看函数的参数/返回值/异常信息
exit/quit 可以退出当前session stop可以完全停掉
如上是关于arthas工具的一些简单用法
4.关于arthas的一些进阶用法
在开始之前的可以先跑个官方提供的demo程序 命令如下
wget https://github.com/hengyunabc/spring-boot-inside/raw/master/demo-arthas-spring-boot/demo-arthas-spring-boot.jarjava -jar demo-arthas-spring-boot.jar
查看JVM
sysprop/sysenv/jvm
如上三个命令 均可以查看jvm 的信息
sm
前面已经提到过了sc命令 sm命令可以查找类的具体函数
加-d参数可以 打印函数的具体信息 还可以查找具体的函数信息
[arthas@316]$ sm java.math.RoundingModejava.math.RoundingMode <init>(Ljava/lang/String;II)Vjava.math.RoundingMode values()[Ljava/math/RoundingMode;java.math.RoundingMode valueOf(I)Ljava/math/RoundingMode;java.math.RoundingMode valueOf(Ljava/lang/String;)Ljava/math/RoundingMode;Affect(row-cnt:4) cost in 28 ms.[arthas@316]$ sm -d java.math.RoundingMode declaring-class java.math.RoundingMode constructor-name <init> modifier private annotation parameters java.lang.String int int exceptions classLoaderHash null declaring-class java.math.RoundingMode method-name values modifier public,static annotation parameters return java.math.RoundingMode[] exceptions classLoaderHash null declaring-class java.math.RoundingMode method-name valueOf modifier public,static annotation parameters int return java.math.RoundingMode exceptions classLoaderHash null declaring-class java.math.RoundingMode method-name valueOf modifier public,static annotation parameters java.lang.String return java.math.RoundingMode exceptions classLoaderHash nullAffect(row-cnt:4) cost in 24 ms.[arthas@316]$ sm java.math.RoundingMode <init>java.math.RoundingMode <init>(Ljava/lang/String;II)VAffect(row-cnt:1) cost in 11 ms.[arthas@316]$
二、简单的案例
1.500异常排查 我们在日常的运维当中 发生500的情况还是蛮多的 这种情况下的问题排查 也是比较复杂的 我们来看下 使用这个工具如何来排查类似的 问题
现有如下报错 "exception":"java.lang.IllegalArgumentException"
curl http://localhost/user/0{"timestamp":1605332785414,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}
使用watch来看下
watch com.example.demo.arthas.user.UserController * '{params, throwExp}'#第一个参数为类名 第二个参数为函数名#该命令可以最后可以增加 -e 参数 表示只有在捕获到异常才打印信息 watch com.example.demo.arthas.user.UserController * '{params, throwExp}' -e#还可以根据耗时来过滤watch com.example.demo.arthas.user.UserController * '{params, throwExp}' '#cost>20'
当我们再次调用 curl命令时 就会有对应的报错
2.查找top N线程
#查找top 3的线程thread -n 3 #查找5秒内 使用top 3的线程thread -n 3 -i 5000#查看线程是否有阻塞thread -b
3.请求报404 问题排查
跟踪所有的servlet函数
trace javax.servlet.Servlet * > /tmp/servlet.txt
查看文件 找到调用时间最长的调用树
本次分享如上
更多可以参考
https://arthas.aliyun.com/doc/