网站Logo GESONG

Arthas

gesong
0
2025-08-29

Arthas 是阿里开源的Java诊断工具,能在不重启应用的情况下实现线上问题排查、性能监控和动态代码热更新。本文将详细介绍其核心功能与使用技巧。

快速安装与启动

# 下载最新版Arthas
curl -O https://arthas.aliyun.com/arthas-boot.jar

# 启动并选择目标JVM进程
java -jar arthas-boot.jar

启动后会显示当前机器上的Java进程列表,输入序号即可附加到目标进程进行诊断。

性能瓶颈定位:trace命令

trace [全限定类名] [方法名] '#cost>阈值' -n 监控次数

核心功能
追踪方法内部调用链,精确到每一行代码的耗时,快速定位性能瓶颈。

使用示例

# 监控saveMedicalDiag方法,仅显示耗时>10ms的调用,最多捕获5次
trace com.example.ClinicService saveMedicalDiag '#cost>10' -n 5

输出解读

`---ts=2025-07-30 12:00:00;thread_name=http-nio-8080-exec-1;id=1e;is_daemon=true;priority=5;
    `---[15.78ms] com.example.ClinicService:saveMedicalDiag()
        +---[0.5ms] com.example.DBUtil:getConnection() 
        +---[12.0ms] com.example.DAO:insert()  # ⚠️ 主要耗时点
        `---[3.2ms] com.example.Logger:writeLog()

注意事项

  1. 默认忽略java.*包下的调用,需逐层排查或使用正则监控多层调用

  2. 正则监控示例:trace -E com.service.*|com.dao.* save*

运行时数据观测:watch命令

watch [类名] [方法名] '{观察表达式}' [参数]

核心功能

观察表达式

作用

示例

params

捕获方法入参

{params[0].userName}

target

获取当前对象属性

target.connectionPoolSize

returnObj

获取返回值

returnObj.status

throwExp

捕获异常信息

throwExp.getMessage()

常用参数

参数

作用

-b

方法调用前触发

-e

异常时触发

-s

方法返回后触发

-f

方法结束后触发

-x 3

设置对象遍历深度

-n 10

仅监控前10次调用

--exclude-class-pattern *Controller

排除特定类

实用场景示例

1. 监控异常时的入参

watch com.example.OrderService createOrder '{params, throwExp}' -e -x 3

输出:

ts=2025-07-30 14:30:00; [cost=45ms] result=ArrayList[
  @Object[][  # 入参
    @OrderRequest[userId="U123", productId=null],  # ⚠️ 空值导致异常
  ],
  ctd.persistence.DAOException: 产品ID不能为空!  # 异常信息
]

2. 监控返回值属性

watch com.example.UserService getUser '{returnObj.age, returnObj.name}' -s

3. 跟踪对象状态变化

watch com.example.CacheService refresh 'target.cacheSize' -f

Arthas核心优势

  1. 无侵入诊断
    无需修改代码或重启服务,直接接入线上JVM进程

  2. 精准定位
    trace精确到代码行级耗时,watch实时捕获运行时数据

  3. 动态热更新
    支持在线修改字节码(https://arthas.aliyun.com/doc/redefine.html)

  4. 全链路支持
    集成火焰图、线程分析、内存监控等全方位工具

封装脚本工具

  • 查看服务器类型

uname -a

  • 根据服务器类型(x86/arm)选择下载arthas工具

没法上传附件,zip文件内部格式如下:

--arthas.zip

-- arthasTools_x86

-- arthas

-- jdk1.8.0_242

-- start.sh

脚本内容如下:

#!/bin/bash

echo "选择Arthas绑定进程号方式:"
echo "1)输入微服务进程号(PID)"
echo "2)输入微服务名称"

read -p "请输入选择的编号(1或2):" user_choice

if [ "$user_choice" -eq 1 ]; then
        read -p "请输入微服务进程号(PID): " pid

elif [ "$user_choice" -eq 2 ]; then
        read -p "请输入微服务名称:" user_input
        serviceName=$user_input
        pid=$(ps -ef |grep -i "$serviceName" | grep java | awk '{print $2}')
else
        echo "无效选择,请选择1或2,请重新执行脚本"
        return 1
fi

# 打印出来查询到的pid
echo "需要监控的微服务PID为:$pid"

if [ -z "$pid" ]; then
		echo "No $serviceName process in this node."
		return 1
fi

# 获取当前路径
current_path=$(pwd)
# 打印当前路径
echo "Current Path: $current_path"
chown -R ossuser $current_path/arthasTools_x86
chgrp -R ossgroup $current_path/arthasTools_x86
chmod 777 -R $current_path/arthasTools_x86/jdk1.8.0_242
su ossuser -c "$current_path/arthasTools_x86/jdk1.8.0_242/bin/java -jar $current_path/arthasTools_x86/arthas/arthas-boot.jar $pid"
  • 将文件上传到节点的/home/sopuser或者/opt/oss/tmp目录下,执行如下解压脚本

/opt/oss/tmp目录需要有可执行权限 chmod 777 /opt/oss/tmp

unzip arthas.zip && chmod +x start.sh
  • 执行start.sh脚本,根据提示输入微服务PID或者微服务名称

. start.sh
  • 输入微服务名称或pid, 执行成功之后会进入arthas的控制页面,可以输入arthas的命令进行定位

# watch:查看接口出入参, -x最大遍历深度为4. 用户可以在ognl表达式里指定更具体的 field。

watch com.huawei.fabricinsight.campus.campusclientservice.impl.EventServiceDelegateImpl getUserList -x 2

watch com.huawei.fabricinsight.campus.campusclientservice.service.experienceanalysis.NetworkAnalysis queryUserIssues -x 3

# watch -x 4无法满足的情况

watch com.huawei.fabricinsight.campus.campusclientservice.service.digitalmap.HomePageService getApInfo "{params,returnObj.get(0).apList}" -x 4

动物装饰