【arthas系】java语言项目如何不停机替换生产某一个class类

先简单介绍下文章中使用是springboot项目,采用的工具是arthas

关于arthas的命令、以及官网地址这里贴以下出来arthas官方文档

这里先说明下,arthas有在线反编译class文件(jad命令)->修改源文件->重新编译(mc命令) 这样的流程来修改文件。这里在网上找到一篇对应这个流程的示例

但是基本上重新编译这个操作很少成功(因为试了几次变更都是因为依赖其他类导致)。所以我这边直接选择使用retransform命令完成的

class文件如何替换

步骤一:将我们修改后源文件编译后的最新的class文件上传服务器

这里项目使用的docker部署

这里使用几个命令来完成,将我们编译好的最新class文件上传到指定目录比如/tmp

当然这里的/tmp为docker里面的目录

docker ps -a | grep 项目名称

找到容器前面的id后,我们使用docker  cp命令将服务器本地文件拷贝到容器/tmp目录下

docker cp  xxx.class  容器id:/tmp

 执行命令如果没有错误提示的话,基本上就成功执行了,当然需要验证的话,我们可以直接进入docker容器里面查看对应/tmp目录是否有该文件。

docker exec -it 容器id  bash 

这里就不再演示了

步骤二:进入容器下载arthas,执行命令

进入容器命令

docker exec -it 容器id  bash 

进来后,执行下面命令下载arthas包,敲下回车键就可以下载对应jar包

curl -O https://arthas.aliyun.com/arthas-boot.jar

java -jar arthas-boot.jar

 按命令1会attach到我们的应用进程

 显示这样子之后,也就代表我们的命令操作完成,也是很正常。执行下面关键命令,如果出来success的字样,代表我们在内存中已经替换完成。

retransform  /tmp/xxxx.class

当然执行完成后,我们在控制台输入exit命令,退出arthas控制台会话。如果我们不需要使用arthas操作其他,可以使用stop命令关闭,不占用线上服务器任何资源、

注意

在我们上面执行完后,在docker容器中我们在arthas客户端命令执行quit或者exit命令,执行关闭下会话,因为有可能因为其他人操作命令session没有关闭,导致执行找不到对应的class文件(执行命令对应目录下的文件实际是存在的)。我们可以尝试完全退出 arthas,执行stop命令

 

 

retransform命令限制

如果提示这个异常错误:retransform error! java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)

是否出现了以下几种情况

  • 不允许新增加 field/method
  • 正在跑的函数,没有退出不能生效,比如下面新增加的System.out.println,只有run()函数里的会生效
public class MathGame {
    public static void main(String[] args) throws InterruptedException {
        MathGame game = new MathGame();
        while (true) {
            game.run();
            TimeUnit.SECONDS.sleep(1);
            // 这个不生效,因为代码一直跑在 while里
            System.out.println("in loop");
        }
    }

    public void run() throws InterruptedException {
        // 这个生效,因为run()函数每次都可以完整结束
        System.out.println("call run()");
        try {
            int number = random.nextInt();
            List<Integer> primeFactors = primeFactors(number);
            print(number, primeFactors);

        } catch (Exception e) {
            System.out.println(String.format("illegalArgumentCount:%3d, ", illegalArgumentCount) + e.getMessage());
        }
    }
}

这个限制请参考官网的同步更新retransform | arthas

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值