背景说明

原本负责开发的同事请假了,测试同事让我帮看看能不能处理一下,避免影响正常发版。

同事反馈某个接口出现异常,返回提示系统繁忙(系统统一异常处理,所以不会返回异常日志)。

我们的系统是在K8S中运行,客户使用频繁,且定时任务较多,因此日志刷新很快,无法准确查到相关错误日志。

排查过程

首先,安装 Arthas,并启用连接应用。

// 下载
curl -O https://arthas.aliyun.com/arthas-boot.jar
// 启动
java -jar arthas-boot.jar

接着,定位接口,查看入参、出参。发现入参数正常,返回不正常。

watch com.*.*Controller s*eport '{params,returnObj,throwExp}' -n 5 -x 3

然后,结合代码,查看关键方法执行栈信息。

trace com.*.*ServiceImpl p**ing -n 5 --skipJDKMethod false

方法错误日志

如上图,发现抛出了类型转换异常,具体发现 字符串转整型异常。

// 前端传入 0.2,使用下列方法会报错
Integer.parseInt(quantity);

结合业务分析,原本功能是支持 Float,该功能是给客户定制需求,客户接收是 整型。所以将代码改为:

// 使用 Hutool 工具类
NumberUtil.parseInt(quantity);

复盘总结

排查思路:

  1. 验证是否稳定复现BUG。请求测试同事协助,获取到接口URL,以及参数。
  2. 获取运行信息。通过Arthas工具,监控获取运行栈。
  3. 定位问题代码。结合业务逻辑,判定代码问题。

优化思路:在确定前端无误的情况,可以直接通过trace命令直接获取运行栈,无需通过watch命令查看出入参。

扩展:Arthas常用命令

核心命令:用于查看JVM和线程的状态。

  • jvm: 查看当前JVM的基本信息。
  • memory: 查看JVM内存使用情况。
  • sysprop: 查看和修改JVM系统属性。
  • sysenv: 查看JVM环境变量。
  • vmoption: 查看和修改JVM诊断相关的选项。
  • heapdump: 生成Java堆转储文件,类似于jmap的功能。
  • thread: 查询线程信息。
  • jad: 反编译Java类。

诊断命令:用于对方法进行观测和追踪。

  • watch:让你能方便的观察到指定函数的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。
  • tt:方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。
  • trace:trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。

watch命令常用于观测异常方法的调用情况,打印详细的参数和异常信息;trace命令常用于追踪关键方法的调用路径,找出性能瓶颈,进行相应优化。

**管理命令:**用于执行OGNL表达式和查找类。

  • ognl:执行 ognl 表达式。
  • sc:查看 JVM 已加载的类信息

扩展:arthas-idea 插件

Arthas-IDEA:可视化生成Arthas命令插件。能通过选定代码,右键快速生成相关 Arthas 命令。

插件文档:https://www.yuque.com/arthas-idea-plugin/help

扩展:用户案例集

用户案例集:https://github.com/alibaba/arthas/issues?q=label%3Auser-case+is%3Aclosed