arthas线上不停机修改bug

安装arthas

shell 复制代码
wget https://alibaba.github.io/arthas/arthas-boot.jar

启动:

java -jar arthas-boot.jar

启动失败

使用jps也没查到对应的进程

发生错误信息

使用进程id启动,报错

进程id查看使用命令:

ps -ef | grep java

详情:

shell 复制代码
[INFO] JAVA_HOME: /usr/local/java/jdk17
[INFO] arthas-boot version: 4.0.5
[INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/4.0.5?mirror=aliyun
[INFO] Download arthas success.
[INFO] arthas home: /home/appadmin/.arthas/lib/4.0.5/arthas
[INFO] Try to attach process 4004020
Picked up JAVA_TOOL_OPTIONS: 
[ERROR] Start arthas failed, exception stack trace: 
java.io.IOException: Operation not permitted
        at jdk.attach/sun.tools.attach.VirtualMachineImpl.sendQuitTo(Native Method)
        at jdk.attach/sun.tools.attach.VirtualMachineImpl.<init>(VirtualMachineImpl.java:82)
        at jdk.attach/sun.tools.attach.AttachProviderImpl.attachVirtualMachine(AttachProviderImpl.java:58)
        at jdk.attach/com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:207)
        at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:100)
        at com.taobao.arthas.core.Arthas.<init>(Arthas.java:27)
        at com.taobao.arthas.core.Arthas.main(Arthas.java:161)
[INFO] Attach process 4004020 success.
[INFO] arthas-client connect 127.0.0.1 3658
Connect to telnet server error: 127.0.0.1 3658
java.net.ConnectException: Connection refused
        at java.base/sun.nio.ch.Net.pollConnect(Native Method)
        at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
        at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547)
        at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602)
        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
        at java.base/java.net.Socket.connect(Socket.java:633)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:188)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:209)
        at com.taobao.arthas.client.TelnetConsole.process(TelnetConsole.java:306)
        at com.taobao.arthas.client.TelnetConsole.main(TelnetConsole.java:166)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at com.taobao.arthas.boot.Bootstrap.main(Bootstrap.java:634)
Usage: arthas-client [--help] [-c <value>] [-f <value>] [-w <value>] [-t
       <value>] [-h <value>] [target-ip] [port]

Arthas Telnet Client

查询日志告知是 : Arthas 在尝试附加到目标 Java 进程(PID 为 4004020)时遇到了问题,并且 Telnet 客户端无法连接到 Arthas Server。

  • 误发生在 sun.tools.attach.VirtualMachineImpl.sendQuitTo(Native Method) 中。
  • 原因分析:
    1. 权限不足:
      • 当前用户(appadmin)没有权限访问目标进程(PID 4004020)。
      • 如果目标进程由 root 用户启动,而你以普通用户运行 Arthas,则会导致权限问题。

使用ps -ef | grep java查看java进程

检查权限

查看目标进程的用户信息:

shell 复制代码
ps -ef | grep 4004020

输出如下:

目标进程由 root 用户启动,而你以普通用户(appadmin)运行 Arthas,因此权限不足

解决方式:

使用下面命令尝试:

shell 复制代码
sudo java -jar arthas-boot.jar 4004020

结果报错:

查询报错原因是:在使用 sudo 提升权限后,系统无法找到 java 命令。

错误原因分析

(1) sudo 的环境变量问题
  • 当你直接运行 java -jar arthas-boot.jar 时,java 是通过当前用户的环境变量(如 PATH)找到的。
  • 使用 sudo 后,环境变量会切换到 root 用户的环境变量,而 root 用户的 PATH 中可能没有包含 java 的路径。

2. 解决方案

(1) 明确指定 java 的完整路径
  • 直接使用 java 的绝对路径来运行命令,避免依赖 PATH 环境变量。

    shell 复制代码
    sudo /usr/local/java/jdk17/bin/java -jar arthas-boot.jar 4004020

可以看到启动成功:

反编译错误的代码位置

接下来使用jad命令 将需要更改的文件先进行反编译,保存下来 ,编译器修改放到tmp目录下

shell 复制代码
 jad --source-only org.mili.order.domain.bo.OrderServiceCompleteVerifyBo > /tmp/OrderServiceCompleteVerifyBo.java

将 OrderServiceCompleteVerifyBo.java下载下来后修改错误的地方(我这里是指删了一个NotNull的一个注解)

查看hash码(类加载器的)

shell 复制代码
sc -d org.mili.order.domain.bo.OrderServiceCompleteVerifyBo | grep classLoaderHash

返回如下:

shell 复制代码
 classLoaderHash   7a765367

将修改后的文件放到tmp/zss/ 目录下,MC命令 用指定的classloader类加载器的hash码重新将类在内存中编译

shell 复制代码
 mc -c 7a765367 /tmp/zss/OrderServiceCompleteVerifyBo.java -d /tmp/zss

替换字节码文件

redefine命令 将编译后的类加载到JVM

下面是上边编译后的.class文件地址

shell 复制代码
redefine /tmp/zss/org/mili/order/domain/bo/OrderServiceCompleteVerifyBo.class

如下图

关闭arthas,测试即可

shell 复制代码
stop

操作记录如下图片

相关推荐
on_pluto_1 天前
【debug】vscode 和 codex 不兼容问题
ide·人工智能·vscode·编辑器
T01156181 天前
艺培场馆课时预约小程序用户端 & 后台联动踩坑上篇(预约、课时、缓存、消息、学员端自身问题)
java·缓存·小程序·bug·全栈项目实战手记·艺培课时系统‘’
zone_z1 天前
07 · 等待事件与 OWI 方法:从 OSW 到 BUG 的完整破案实录
linux·数据库·oracle·ffmpeg·bug·troubleshooting
承渊政道1 天前
【Python编程—从入门到实践】(Python操作列表深度教程:循环、切片、元组与代码风格)
开发语言·python·pycharm·列表·元组·切片
一杯原谅绿茶1 天前
VSCode的Eclipse插件-编译Eclipse项目
ide·vscode·eclipse
布值倒区什么name1 天前
Pycharm2026找不到编译器 点击运行运行不了
开发语言·python·pycharm
虎虎(_ _)。゜zzZ1 天前
PyCharm制表符与空格完全指南
pycharm·pep8·代码格式化·制表符与空格·python代码规范·缩进配置
etc95272 天前
keil下如何指定stack和heap地址
ide·mcu
JTaoX2 天前
PyCharm 连接本地虚拟机完整指南
ide·python·pycharm
黑猫学长呀2 天前
【驱动开发常见问题】编译出现rm: cannot remove `asm/arch‘: Is a directory
驱动开发·单片机·嵌入式硬件·bug·编译报错·kernrl