使用经验分享
线上故障排查思路:
1、紧急处理,优先保障服务可用(如切换vip,主备容灾)
2、保留第一现场,通过jstack -l {pid} > jvmtmp.txt ,打印栈信息 (后续可以在gceasy官网上传报文进行分析)
3、通过arthas工具进行线上故障问题。执行命令如下
dashboard,优先通过看板,找到问题线程id
thread {id},查看问题线程的栈信息
watch {class} {method} {ognl表达式},观察问题方法的上下文
前言
arthas是阿里的一款线上故障分析工具,对jvm当前的上线文可以进行实时监控,下文会介绍我在实际过程中是如何使用arthas来定位问题的。
背景
测试反应系统反应较慢,后端服务无法进行响应;
故障分析
一个月前的测试使用中并未出现该问题,原因可能:
1、近期业务编码出现问题(多层循环、逻辑错误等);
2、近期大数据量测试,数据量增大内存不够;
dashboard
通过看板形式,分析当前jvm整体状态
[arthas@22683]$ dashboard
通过图片可以看出,线程http-nio-9030-exec-8、http-nio-9030-exec-7执行耗时查过1小时,并且伴随着大量的GC线程。初步判断线程可能存在深度递归或者死循环,产生了大量内存,JVM疲于GC,GC期间系统会发生STW(Stop The World),且占用了大量CPU资源,因此导致其他服务线程无法正常工作
thread
知道问题线程后,我们可以利用thread分析下线程状态
monitor
为了验证我们得到的业务代码(calcCollectionDate(CashFlowAnalyzeServiceImpliava:1780))是否是问题发生处,我们可以利用monitor进行监控,每5秒打印该方法的调用频率:
monitor -c 5 com.psbc.abs.assetpool.service.assetpool.impl.CashFlowAnalyzeServiceImpl calcCollectionDate
watch
通过代码分析,com.psbc.abs.assetpool.service.assetpool.impl.CashFlowAnalyzeServiceImpl calcCollectionDate用于生成产品计算日归集日。因此我们利用watch方法,尝试打印它的上下文,找到关键信息
watch com.psbc.abs.assetpool.service.assetpool.impl.CashFlowAnalyzeServiceImpl calcCollectionDate "params[0].getBillDataVO()" -x 2 | grep billCode
结论
最终,我们定位到了故障起因。代码中有while循环,当页面输入的条件始终满足while时就会出现死循环。当系统资源不够使用时发生频繁GC,最终消耗大量CPU资源,系统卡顿。