arthas是什么?
Arthas 是Alibaba开源的Java诊断工具,由于其强大的问题排查及诊断能力,自其开源以来广受开发者的关注和使用,多次登顶 GitHub Trending,并得到国内多家技术媒体的推荐分享。
官方文档地址:https://arthas.aliyun.com/doc/
github地址:https://github.com/alibaba/arthas
arthas能做什么?
当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
thread
启动arthas
java -jar arthas-boot.jar
选择需要附着的java进程号 输入arthas对应该进程号的数字编号:25
查看cpu使用率最高的5个线程
thread -n 5
查看线程高的堆栈信息
thread 33
原因分析:
定位到代码位置:bussiness.common.SendLogThread.run(SendLogThread.java:28)
查看源码:
public void run() {
ArrayList logList = null;
while(true) {
while(true) {
try {
logList = new ArrayList();
for(int i = 0; i < 5; ++i) {
BussinessLogVO logVO = (BussinessLogVO)queue.poll();
if (null != logVO) {
logger.debug("取出:" + logVO.getBussinessId());
logList.add(logVO);
}
}
if (logList.size() > 0) {
try {
BussinessLogThread thread = new BussinessLogThread();
thread.setLogList(logList);
logger.debug("发送:" + JSONObject.toJSONString(logList));
BussinessLogUtil.saveLog(BUSSINESS_LOG_URL, thread);
} catch (Exception var4) {
logger.error("日志保存失败", var4);
}
}
} catch (Exception var5) {
logger.error("发送日志发生异常", var5);
}
}
}
}
其中BussinessLogVO logVO = (BussinessLogVO)queue.poll();这一行在死循环中用到了ConcurrentLinkedQueue.poll,应该要用take或者带超时时间的poll。不然线程资源一直不会释放掉,cpu持续占用。
thread 其他命令
thread -b 找出当前阻塞其他线程的线程
thread –state 查看指定状态的线程
tarce调用跟踪
查看方法内部调用路径,并输出方法路径上的每个节点上耗时,使用 trace 命令可以一层一层追踪耗时在哪里 ,在进行性能调优的时候十分有效。
trace className methodName
以上命令可以轻松定位信源qq音乐方法searchByDissId耗时在哪里。
命令后面添加 '#cost > 10' 可以根据耗时来过滤
ps:在进行 trace 的时候,只要调用链中有异步,堆栈就会断掉,无法 trace 到子线程内部
monitor 命令
monitor -c 100 className methodName
监控100s内该类的方法的执行情况
监控项 | 说明 |
---|---|
监控项 | 说明 |
timestamp | 时间戳 |
lass | Java类 |
method | 方法(构造方法、普通方法) |
total | 调用次数 |
success | 成功次数 |
fail | 失败次数 |
rt | 平均RT |
fail-rate | 失败率 |
sc
“Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息
sc -d -f className
stack
输出当前方法被调用的调用路径
stack className methodName
很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。
对研发排查问题和查看逻辑是否走到非常非常有用。
watch
方法执行数据观测
- watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后
- 4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
- 这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参
- 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在
参数名称 | 参数说明 |
---|---|
参数名称 | 参数说明 |
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
express | 观察表达式 |
condition-express | 条件表达式 |
[b] | 在方法调用之前观察 |
[e] | 在方法异常之后观察 |
[s] | 在方法返回之后观察 |
[f] | 在方法结束之后(正常返回和异常返回)观察 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[x:] | 指定输出结果的属性遍历深度,默认为 1 |
jvm
查看当前JVM整体信息,包括jvm的内存管理、线程情况、垃圾回收等
dashboard
当前系统的实时数据面板
还犹豫什么?赶紧去试试吧~