目录
参考
Alibaba开源的Java诊断工具Arthas-进阶教程
爱上Java诊断利器Arthas
arthas-idea-plugin
用户实战
一、启动
# 避免中文乱码
wget https://arthas.aliyun.com/arthas-boot.jar;java -jar arthas-boot.jar --target-ip 0.0.0.0
java -Dfile.encoding=UTF-8 -jar arthas-boot.jar
二、支持的ognl表达式
- loader
- clazz
- method
- target
- params
- returnObj
- throwExp
- isBefore
- isThrow
- isReturn
三、监听参数
# 监听所有参数
watch com.xxx.iot.web.DeviceController * '{params}' -x 2
# 监听所有参数
watch com.xxx.iot.web.DeviceController * params -x 2
# 监听第几个参数
watch com.xxx.iot.web.DeviceController * params[0] -x 2
-x
表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是1。
监听Controller 的参数和返回值
监听完整参数和返回值
# 只监听参数
watch com.xxx.iot.web.DeviceController * '{params}' -x 2
# 或者
watch com.xxx.iot.web.DeviceController * params -x 2
# 监听所有方法
watch com.xxx.iot.web.DeviceController * '{params, target, returnObj}' -x 2
# 监听对应方法
watch com.xxx.iot.web.DeviceController getOnlineByCode '{params, target, returnObj}' -x 2
当请求如下时
Result<PageDTO<DriverDTO>> fetchDriverByDeviceCode(@Validated @Parameter(description = "实体", name = "param", required = true) @RequestBody DevicePageQueryDTO param)
arthas显示如下:
method=com.xxx.iot.web.DeviceController.getOnlineByCode location=AtExit
ts=2023-04-10 16:57:49; [cost=16.8166ms] result=@ArrayList[
@Object[][
@DeviceCodeBatchQueryDTO[DeviceCodeBatchQueryDTO(deviceCodes=[1584381959985602561, 1589581864182480897, 150077101, TJ0205103, TJ0205211])],
],
@DeviceController[
log=@Logger[Logger[com.xxx.iot.web.DeviceController]],
deviceService=@DeviceServiceImpl[com.xxx.iot.service.impl.DeviceServiceImpl@5236007a],
],
@Result[
serialVersionUID=@Long[1],
traceId=null,
code=@Integer[0],
msg=null,
data=@ArrayList[isEmpty=false;size=5],
uri=null,
],
]
监听kafka消费
# 方法 public void process(JSONObject messageBody,PhysicalDataModelDTO tdl,DeviceType deviceType,ProductDTO product,String productKey,String deviceKey, String messageId,String deviceMessageId) {)
watch com.xxx.iot.receiver.listener.KafkaPropertyReceiver process '{params, target, returnObj}' -x 2
监听单个参数
watch com.xxx.iot.receiver.listener.KafkaPropertyReceiver process '{params[0], target, returnObj}' -x 2
效果如下:
method=com.xxx.xxx.receiver.listener.KafkaPropertyReceiver.process location=AtExit
ts=2023-04-10 17:14:30; [cost=24.4472ms] result=@ArrayList[
@JSONObject[
@String[deviceKey]:@String[yangchen1],
@String[messageId]:@String[54691],
@String[params]:@JSONObject[isEmpty=false;size=11],
@String[productKey]:@String[cu9f6bf82fc4444cc18774f2bc7d370685],
@String[ts]:@Long[1681118069925],
@String[version]:@String[1.0],
],
@KafkaPropertyReceiver[
log=@Logger[Logger[com.xxx.iot.receiver.listener.KafkaPropertyReceiver]],
pushService=@PushServiceImpl[com.xxx.iot.push.impl.PushServiceImpl@1703b898],
mongoTemplate=@MongoTemplate[org.springframework.data.mongodb.core.MongoTemplate@13857408],
PARAMS=@String[params],
productService=@ProductServiceImpl[com.xxx.iot.service.impl.ProductServiceImpl@196a3471],
log=@Logger[Logger[com.xxx.iot.receiver.listener.KafkaPropertyReceiver]],
title=@String[属性上报],
],
null,
]
监听异常
watch命令支持-e选项,表示只捕获抛出异常时的请求:
watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e
按照耗时进行过滤
watch命令支持按请求耗时进行过滤,比如:
watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'
监听参数比较
当访问 user/1 时,watch命令没有输出
当访问 user/101 时,watch会打印出结果。
watch com.example.demo.arthas.user.UserController * returnObj 'params[0] > 100'
四、变量和方法
查询静态成员变量值
ognl @com.xxx.iot.ArthasTest@hashSet
# 增加classloader -x增加数据展开层级
ognl -c 31221be2 '@com.xxx.core.config.DynamicTableThreadLocal@PROJECT_IDS' -x 2
修改静态成员变量值
ognl -c 31221be2 '@com.xxx.core.config.DynamicTableThreadLocal@PROJECT_IDS.get("iot_xxx_data").remove("1607xxx2482")'
查询配置类具体属性的值
## 方法一
ognl '@com.xxx.common.core.util.ServiceHelper@getBean("mqConfig").eventConcurrency'
通过类加载器查看Spring容器中对象所有属性
# 1、获取类加载器
[arthas@17860]$ sc -d *MqConfig | grep class-loader
class-loader +-sun.misc.Launcher