arthas-线上问题定位好帮手
2021-10-08 18:55:43 40 举报
AI智能生成
使用arthas定位线上bug
作者其他创作
大纲/内容
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到JVM的实时运行状态?
怎么快速定位应用的热点,生成火焰图?
使用场景
curl -O https://arthas.aliyun.com/arthas-boot.jar
快速安装
java -jar arthas-boot.jar
启动成功之后,会在 ~/.arthas/lib/ 目录下,下载相应版本依赖包
如果不成功,可以查看~/logs/arthas/ 目录下的日志
如果下载速度比较慢,可以使用aliyun的镜像:java -jar arthas-boot.jar --repo-mirror aliyun --use-http
java -jar arthas-boot.jar -h 使用该命令,可以查看更多帮助信息
快速启动
java -jar arthas-boot.jar --target-ip 0.0.0.0
浏览器远程访问: http://ip:8563
远程访问
1. 将启动之后的lib目录依赖包打包,部署到离线环境节点的 ~/.arthas 目录下2. 复制arthas-boot.jar 部署到离线环境节点中3. 参考快速启动步骤使用arthas
离线安装
rm -rf ~/.arthas/rm -rf ~/logs/arthas
快速卸载
可以查看系统的实时数据面板
q 或 ctrl+c 可以退出数据面展示
dashboard dashboard -n 10 dashboard -i 2000
-i 指定命令执行间隔,默认5000毫秒 -n 指定命令执行次数
官网操作详解
dashboard
查看当前线程信息,查看线程的堆栈
thread -i 1000 : 统计最近1000ms内的线程CPU时间。thread -n 3 -i 1000 : 列出1000ms内最忙的3个线程栈
id 指定线程id-n 指定最忙的前N个线程并打印堆栈-b 找出当前阻塞其他线程的线程(注意, 目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持。)-i 指定cpu使用率统计的采样间隔,单位为毫秒,默认值为200
当没有参数时,显示第一页线程的信息,默认按照CPU增量时间降序排列
thread
查看当前JVM信息
jvm
查看当前JVM的系统属性(System Property)
sysprop
查看当前JVM的环境属性(System Environment Variables)
sysenv
查看,更新VM诊断相关的参数
vmoption
查看logger信息,更新logger level
logger -n 查看指定名字的logger信息
logger -c 手动输入hashcode:-c <hashcode> 查看指定classloader的logger信息
logger --name ROOT --level debug 更新日志级别
logger --include-no-appender 默认情况下,logger命令只打印有appender的logger的信息。如果想查看没有appender的logger的信息
logger
Search-Class 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息
-d 参数可以打印出类加载的具体信息,方便定位类加载问题
-f 输出当前类的成员变量信息(需要配合参数-d一起使用)
sc
Search-Method的简写,查看已加载类的方法信息
sm java.lang.String
sm -d java.lang.String toString
sm
将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑
jad java.lang.String
反编译时只显示源代码 jad --source-only demo.MathGame
反编译指定的函数 jad demo.MathGame main
反编译时不显示行号 jad --lineNumber false demo.MathGame
jad
Memory Compiler/内存编译器,编译.java文件生成.class
mc /tmp/Test.java
可以通过-c参数指定classloader: mc -c 327a647b /tmp/Test.java
可以通过-d命令指定输出目录: mc -d /tmp/output /tmp/ClassA.java /tmp/ClassB.java
mc
加载外部的.class文件,retransform jvm已加载的类
指定的 .class 文件retransform /tmp/MathGame.class
retransform
-b 在方法调用之前观察
-e 在方法异常之后观察
-s 在方法返回之后观察
-f 在方法结果之后观察,默认打开,前面3个默认关闭
-x 指定输出结果的属性遍历深度
方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 \bOGNL 表达式进行对应变量的查看
watch org.apache.knox.gateway.util.urltemplate.Parser parseLiteral \
watch
生成应用热点的火焰图。本质上是通过不断的采样,然后把收集到的采样结果生成火焰图。
profiler start 默认情况下,生成的是cpu的火焰图,即event为cpu。可以用--event参数来指定。
profiler getSamples 获取已采集的sample的数量
profiler stop --file /tmp/output.svg
profiler stop --format html
profiler stop --file /tmp/result.html
profiler stop 停止采样,默认情况下,生成的结果保存到应用的工作目录下的arthas-output目录。可以通过 --file参数来指定输出结果路径
http://localhost:3658/arthas-output/
profiler
常用命令
通过通配符 * 匹配,也可以 *XXX* 格式匹配
问题1. 我如何查找某个只知道大概的类,或者说我想确认某个类是否已被系统加载?
jad反编译一个类,也可以指定到具体类中具体的方法
watch com.aurora.jvm.MathGame primeFactors \
问题2. 如何查看一个class类的具体信息?
watch 命令结合ognl表达式
问题3. 如何跟踪某个方法的返回值、入参.... ?
thread -n 3 # 查看最繁忙的三个线程栈信息
thread # 以直观的方式展现所有的线程情况
thread -b #找出当前阻塞其他线程的线程
问题4. 查看最繁忙的线程,以及是否有阻塞情况发生?
1. 然后使用外部工具编辑内容jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java2. 然后使用外部工具编辑内容,再编译成classmc /tmp/UserController.java -d /tmp3. 重新载入定义的类,就可以实时验证修改的代码redefine /tmp/com/example/demo/arthas/user/UserController.class
问题5. 如何验证自己的代码猜想,临时更改代码运行?
monitor -c 5 com.aurora.jvm.MathGame primeFactors
问题6. 如何测试某个方法的性能问题?
tt -t com.aurora.jvm.MathGame primeFactors # 追踪方法的响应时间情况
trace com.aurora.jvm.MathGame run '#cost > 10' # 据调用耗时过滤
问题7. 其他的追踪方法
常见问题
官网操作手册
Arthas学习
0 条评论
回复 删除
下一页