java 热替换(二)

当我发现通过普通的agent技术只能实现“方法体内的代码替换”,于是开始在网上寻找新技术能较好的解决热替换的问题,第1个发现的便是已经比较成熟的工具dcevm

(1)dcevm工具

现在的jvm不是只支持“方法内的代码替换”吗,dcevm便霸气的改了jvm,其安装工具也就是直接替换jdk下面的jvm.dll。听起来是不是很可怕很不靠谱,jvm这么底层的东西也是能动的?先前我向同事分享这个工具的时候,他们第一反映也是这样。。。

但dcevm的实际使用起来还是不错的,并且官网文档一直在强调推荐使用在开发环境和测试环境,并不推荐使用在生产环境。(dcevm的定位非常务实)

dcevm是开源的,不过因为部分原因没拿到代码,这里就做一下工具的调试

首先写一个很简单的例子,循环定时打印“hello world”

class SimplePrinter {
    SimplePrinter(){}

    void print(){
        System.out.println("hello world");
    }
}
public class Main {
    public static void main(String[] args){
        while(true){
            try {
                SimplePrinter clazz = new SimplePrinter();
                clazz.print();
                Thread.sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果如下:(一定要调试运行,调试才会开启eclipse的热替换功能)

hello world
hello world
hello world
hello world

我们先做1个尝试,在simpleprinter的print方法中多加1个打印信息

class SimplePrinter {
    SimplePrinter(){}

    void print(){
        System.out.println("hello world");
        System.out.println("changed in method");
    }
}

保存后,会发现控制台打印的内容变了

hello world
hello world
changed in method
hello world
changed in method

我们再做另外一次尝试,在simplePrinter中新增一个方法并调用,如下

class SimplePrinter {
    SimplePrinter(){}

    void print(){
        System.out.println("hello world");
        System.out.println("changed in method");
        newMethod();
    }

    void newMethod(){
        System.out.println("new method");
    }
}

点击保存,会弹如下的对话框

java 热替换(二)_第1张图片

关键字是“hotcode replace failed”,在网上查了些资料,并用git拉了eclipse的源代码看了下,知道了eclipse里实现的“热替换”叫“hotcode”,是集成在其调试模块的。eclipse里面使用的是自带的sun/…/tools.jar包(具体路径忘了),不同于我们先前使用的jdk/lib/tools.jar包,记得应该是一样的。这就意味着eclipse支持的“热替换”也只支持“方法内的代码热替换”,从我们先前的例子也可以得出。

于是,就需要更强大的“热替换工具”了,我们先试试dcevm

其安装过程很简单,前面也介绍过,dcevm安装过程就是把修改后的jvm.dll替换你本机上jdk下面的jvm.dll,这个安装实现很简单,难的是dcevm是怎么修改jvm得到优化后的jvm.dll的,好在我们不用讨论这个问题。。。

java 热替换(二)_第2张图片

选择使用的jdk进行替换,我们再来试一下上面的测试例子

(2)jrebel工具

相比dcevm工具的直接,jrebel在java层面解决了“热替换”的问题。在网上查资料的过程中,很多网友盛赞了jrebel,赞其在线上环境真的解决了很多问题。不过jrebel是收费,不知道他们是不是用的“破解版”。。。

心痒难耐,下了个试用版试试。

jrebel似乎是为web应用量身制作的,从网上看的资料似乎可以和tomcat很好的集成。对于非web项目也有相应的解决方案。我先下了个jrebel的eclipse插件版在开发环境体验,如果不错发现可以引进项目的话,在linux环境下可以使用shell命令运行。不错

体验工具总是很简单的,想探究jrebel的原理就比较难了,似乎不是自己技术水平可以做的事。好在jrebel作者大方的再几篇博客中谈及了一下jrebel的实现原理,可以想象一下。。。

你可能感兴趣的:(java)