少年,想线上热更新代码不?

2019-02-19 15:57:23 +08:00
 hengyunabc

背景

尽管在生产环境热更新代码,并不是很好的行为,很可能导致:热更不规范,同事两行泪。

但很多时候我们的确希望能热更新代码,比如:

线上排查问题,找到修复思路了,但应用重启之后,环境现场就变了,难以复现。怎么验证修复方案?

又比如:

本地开发时,发现某个开源组件有 bug,希望修改验证。如果是自己编译开源组件再发布,流程非常的长,还不一定能编译成功。有没有办法快速测试?

Arthas 是阿里巴巴开源的 Java 应用诊断利器,深受开发者喜爱。

下面介绍利用 Arthas 3.1.0 版本的 jad/mc/redefine 一条龙来热更新代码。

Arthas 在线教程

下面通过 Arthas 在线教程演示热更新代码的过程。

在例子里,访问 curl http://localhost/user/0,会返回 500 错误:

{
    "timestamp": 1550223186170,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "java.lang.IllegalArgumentException",
    "message": "id < 1",
    "path": "/user/0"
}

下面通过热更新代码,修改这个逻辑。

jad 反编译代码

反编译UserController,保存到 /tmp/UserController.java文件里。

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java

修改反编绎出来的代码

用文本编辑器修改/tmp/UserController.java,把抛出异常改为正常返回:

    @GetMapping(value={"/user/{id}"})
    public User findUserById(@PathVariable Integer id) {
        logger.info("id: {}", (Object)id);
        if (id != null && id < 1) {
            return new User(id, "name" + id);
            // throw new IllegalArgumentException("id < 1");
        }
        return new User(id.intValue(), "name" + id);
    }

sc 查找加载 UserController 的 ClassLoader

$ sc -d *UserController | grep classLoaderHash
 classLoaderHash   1be6f5c3

可以发现是 spring boot 的 LaunchedURLClassLoader@1be6f5c3 加载的。

mc 内存编绎代码

保存好/tmp/UserController.java之后,使用 mc(Memory Compiler)命令来编译,并且通过-c参数指定ClassLoader

$ mc -c 1be6f5c3 /tmp/UserController.java -d /tmp
Memory compiler output:
/tmp/com/example/demo/arthas/user/UserController.class
Affect(row-cnt:1) cost in 346 ms

redefine 热更新代码

再使用 redefine 命令重新加载新编译好的UserController.class

$ redefine /tmp/com/example/demo/arthas/user/UserController.class
redefine success, size: 1

检验热更新结果

再次访问 curl http://localhost/user/0,会正常返回:

{
    "id": 0,
    "name": "name0"
}

总结

Arthas 里 jad/mc/redefine 一条龙来线上热更新代码,非常强大,但也很危险,需要做好权限管理。

比如,线上应用启动帐号是 admin,当用户可以切换到 admin,那么

所以:

最后,Arthas 提醒您: 诊断千万条,规范第一条,热更不规范,同事两行泪

Arthas 实践系列

公众号

欢迎关注横云断岭的专栏,专注 Java,Spring Boot,Arthas,Dubbo。

3643 次点击
所在节点    程序员
4 条回复
murmur
2019-02-19 15:58:34 +08:00
这个东西跟 idea 的热部署插件有什么区别
hengyunabc
2019-02-19 16:15:14 +08:00
@murmur 没有用过,idea 的更多可能是本地开发用的。Arthas 是线上命令行工具。
realkenshinji
2019-02-19 18:34:20 +08:00
用 Elixir 不就行了么
hellowes
2019-02-19 21:13:23 +08:00
阿里 Java 就是比前端 NB 100 背

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/536589

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX