常见的服务CPU过高Arthas快速排查问题详细笔记
官网介绍:简介 | arthas
1、排查CPU占用过高问题
- 首先,通过 dashboard + thread 命令,基本可以在几秒钟内一键定位问题,找出消耗 CPU 最多的线程和方法栈;
- 然后,直接 jad 反编译相关代码, 来确认根因;
- 此外,如果调用入参不明确的话,可以使用 watch 观察方法入参,并根据方法执行时间来过滤慢请求的入参。
1.1 基本命令说明
- ① thread -n 10 命令查看CPU占用资源最高的10条线程。
- ② thread 命令查看线程的执行信息,定位到具体的方法。
- ③ monitor 命令对目标方法进行监控,查看方法的调用次数与耗时。
- ④分析 monitor 命令查询出的结果,定位问题根源,确定是由于调用过于频繁导致的,还是内部代码逻辑问题。
- ⑤使用 jad 命令反编译 class 文件,根据前面分析的原因排查代码并改善。
1.2 排查具体的类和方法
(1) 明确是哪个进程,先进入Arthas,进入问题进程,使用命令:dashboard 查看top的 线程(或者 thread -n 5 看前五)
(2)使用命令 thread 耗资源最大线程号 查看具体的内容,分析出可疑的类方法
(比如 类:org.LatencyUtils.SimplePauseDetector$SimplePauseDetectorThread 方法:run)
(3)使用命令 jap org.LatencyUtils.SimplePauseDetector$SimplePauseDetectorThread 反编译出代码
(4)根据反编译出的内容 查看上下文调用链路,定位出哪个方法的问题(如果判断不出慢在怎样的入参,继续走下步)
(5)使用命令 watch org.LatencyUtils.SimplePauseDetector$SimplePauseDetectorThread run '{params}' '#cost>100' -x 2
(如上命令,表示需要监控耗时超过 100 毫秒的 run 方法的入参,并且输出入参,展开 2 层入参参数)
2、排查线程阻塞问题
2.1 基本命令说明
- ① thread 筛选所有阻塞状态的线程。
- ②根据线程名称定位具体的业务模块,再选中该业务中的一条线程查看堆栈信息。
- ③根据线程堆栈信息定位导致阻塞的具体方法,再利用 stack 命令查看方法堆栈信息。
- ④利用 jad 工具反编译源码,分析业务逻辑代码并改善。
3、排查死锁问题
- ①利用 Arthas 来检测死锁特别简单,只需要执行一行命令 thread -b 即可。
4、排查方法执行过慢问题
4.1 基本命令说明
- ①通过 trace 命令排查方法执行速度, trace xx类 xx方法 '#cost>50ms' ,观测执行时间大于 50ms 的该方法的调用信息。
- ②可以结合正则表达式,同时排查多个类、多个方法, trace -E ClassA|ClassB method1|method2|method3 。
4.2 trace: 排查上下文耗时情况
# 1、trace函数指定类的指定方法 trace demo.MathGame run
#2、执行1次后退出 trace demo.MathGame run -n 1
#3、据调用耗时过滤,trace大于1的调用路径 trace demo.MathGame run '#cost > 1'
4.3 stack:输出当前方法被调用的调用路径
#1、获取primeFactors的调用路径 stack demo.MathGame primeFactors
5、动态修改线上代码
5.1 基本命令说明
上线之后,发现代码有一处小地方存在逻辑错误需要更改,可以直接线上修改,而不用重启。
- ①通过 jad 将要修改的类反编译为 .java 文件,输出到指定目录。
- ②本地纠正 .java 文件后,通过 mc 命令重新编译 .java 文件。
- ③通过 retransform 命令将刚编译的 .class 文件再次加载到JVM中。