作者:鲍凤其
爱可生 dble 团队开发成员,主要负责 dble 需求开发,故障排查和社区问题解答。少说废话,放码过来。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
- https://github.com/alibaba/arthas
- https://github.com/alibaba/arthas/blob/master/README_CN.md
- https://www.cnkirito.moe/arthas-redefine/
- https://manuals.jrebel.com/jrebel/standalone/maven.html
- https://manuals.jrebel.com/jrebel/advanced/launch-quick-start.html#quick-start
关于 dble 小版本修改代码的热更新,主要调研了两种工具:
- arthas
- jrebel
使用 arthas 更新小版本时,需要运维人员直接操作变更的 class 文件并修改,需要一套运维规范。
使用 jrebel 后,jrebel 可以对 dble 的 jar 包配置一个 class 目录,jrebel 自动监听 class 目录中 class 文件的变化,监听到变化后自动加载类,此外该软件需要付费。
在进行小版本升级时,需要控制 dble 的版本号,因此每次热更新时需要替换 Versions.class 文件维护 dble 的版本号,经测试,发现 jrebel 对静态类的支持并不友好,实际测试没有生效,相比较而言 arthas 则可以生效。因此下面主要对 arthas 在 dble 中的使用进行说明。
前置环境
- jre,使用 dble 的 jre 即可
- 搭建好的 3.20.10.0 版本 dble 环境
*arthas 使用
安装
下载地址:https://github.com/alibaba/arthas/releases,下载最新版本即可,以下测试使用的是 3.4.5 版本
$ cd /opt/arthas
$ wget https://github.com/alibaba/arthas/releases/download/arthas-all-3.4.5/arthas-bin.zip
$ unzip arthas-bin.zip
其他安装方式请参考:https://arthas.aliyun.com/doc/install-detail.html
使用
执行下面的语句后,会进入 arthas 的交互界面:
$ java -jar arthas-boot.jar <dble_pid>
下面以在 dble 中简单修改一行日志为例:
在 3.20.10.0 版本的 dble 中,当输入"optimize a; " 这种 dble 不认识的语句时,日志中会输出 “Unsupported statement:optimize a” 这样的日志,如下图:
下面我们通过 arthas 修改这个日志输出,以下操作都是在 arthas 的命令行界面操作。
jad 反编译
$ jad --source-only com.actiontech.dble.server.ServerQueryHandler > /tmp/ServerQueryHandler.java
下面是反编译文件里面截取的相关代码片段:
case 254: {
LOGGER.info("Unsupported statement:" + sql);
this.service.writeErrMessage(1149, "Unsupported statement");
return;
}
sc 查找类加载器
$ sc -d com.actiontech.dble.server.ServerQueryHandler | grep classLoaderHash
classLoaderHash 18b4aac2
mc 内存编译
在编译之前可以将之前反编译源码文件里的代码修改掉,比如修改为如下片段:
case 254: {
LOGGER.info("Unsupported statement test test test test test:" + sql);
this.service.writeErrMessage(1149, "Unsupported statement");
return;
}
下面我们通过 mc 命令将修改后的反编译源码文件编译为 class 文件。mc 命令中 -c 后面的值 18b4aac2 即 sc 查找到的 ServerQueryHandler 类加载器的 hash 值。
redefine 热更新代码
其实在这里我们也可以通过在本地修改对应版本的源文件,本地编译好后上传到 /tmp/com/actiontech/dble/server/ 路径下,再执行 redefine,效果是一样的:
$ redefine /tmp/com/actiontech/dble/server/ServerQueryHandler.class
redefine success, size: 1, classes:
com.actiontech.dble.server.ServerQueryHandler
到此为止,ServerQueryHandler 类的更新就结束了。下面我们来看下效果:
以上方式是通过 arthas 的交互界面的方式完成的,arthas 也可以通过非交互方式来执行命令:
$ java -jar arthas-boot.jar <dble_pid> -c "redefine /tmp/com/actiontech/dble/server/ServerQueryHandler.class" > /dev/null
通过此方式,可以更方便的通过脚本管理整个流程。
网友评论