前言

对于线上bug排查神器Arthas,一直没有实际使用过.正好近期碰到一次比较诡异的线上bug,记录一下使用Arthas的排查经过

线上异常

早上实施的同学反馈了客户一个问题,说是单据保存不了.页面只抛出了一个空异常.
由于单据页面的保存方法拦截了所有的异常类,一般会抛出详细的异常信息.返回空message一般都是空指针异常.因为近期没有发过更新补丁,客户表示早上突然不能使用.但测试环境无法重现.

分析

初步判断是代码中有空指针异常,但平台框架拦截了所有异常,日志没有打印相关的异常信息.无法定位异常代码具体位置.

处理方式

以前碰到类似情况,会修改代码,打印详细的异常信息.但是要重新打包,再给客户发布,较为浪费时间.
这次试用Arthas做一次线上排查

准备工作

客户服务器是windows环境,已经安装了jdk.

下载Arthas

下载地址 https://github.com/alibaba/arthas/releases

arthas 查询 try restarting transacti arthas 异常_异常信息


(因为本地已经最新的jar包,就直接拷到了客户服务器)进入jar包目录,启动Arthas

java -jar arthas-boot.bar

打开机器上所有的java进程

arthas 查询 try restarting transacti arthas 异常_java_02


输入序号,回车,进入要排查问题的进程

arthas 查询 try restarting transacti arthas 异常_异常信息_03


使用help命令,查看arthas的命令列表

arthas 查询 try restarting transacti arthas 异常_java_04


本次主要是用watch命令,对关键方法的异常信息进行观察

watch -h

查看watch命令的使用说明

arthas 查询 try restarting transacti arthas 异常_空指针异常_05


对关键方法的异常信息进行观察

watch -f com.xx.xx.service.workOrderService checkSave throwExp

在页面执行保存操作,触发异常.的到如下信息

可以看到异常代码发生在workOrderService 类的具体位置

arthas 查询 try restarting transacti arthas 异常_java_06


再结合代码排查,发现问题出在前端传参过程中,有个关键值丢失了.用户在前端通过自定义移除了关键字段.导致参数丢失.之后就很好办了,前端优化用户自定义功能,关键字段不允许移除,只能进行隐藏操作.

使用命令说明

这是很简单的使用watch命令
watch [参数] [类的全路径] [方法名] [返回参数] [返回参数条件]
eg:watch -f com.xx.xx.service.workOrderService checkSave throwExp

常用参数说明
-f 要观察的方法执行完后触发
-b 要观察的方法执行前触发
-e 要观察的方法异常时触发

返回参数说明
params 入参信息
returnObj 返回值信息
throwExp 异常信息

这里只介绍了很少的几种参数,详细的参数信息可以使用
watch -h 查看官方说明

写在后面

本次只是记录了Arthas很简单的一次应用
此外也可以查看更详细的信息,调用链,类加载器,反编译代码,在线热更新,通过浏览器远程使用等
大大方便了线上问题排查效率

吐槽:windows环境下,Arthas不能使用按键[↑]调出上一条输入的命令,使用体验不如linux环境