引用参考第二条 - Arthas提醒您: 诊断千万条,规范第一条,热更不规范,同事两行泪

起因

在一次迭代中,出现了一个低级错误,if 语句中的判断逻辑出现了错误,刚好这个功能场景在开发和测试过程中很少触发,使用的用户也不多,不过的确影响到了少部分用户,所以还是需要进行修复。

想着只是更新一行代码,如果走正常的发布流程,需要通过以下步骤:

提交代码 -> 提测打包 -> 测试环境git验证 -> Release 环境验证 -> 预发环境验证 -> 线上环境

如果你的应用体积不小,而且线上机器很多,花费的时间可能足够喝很多杯 Java :-O


Arthas

之前使用过 Alibaba 开源的诊断工具 Arthas ,下图是官方文档中提到的功能:

不仅可以用来排查问题,还能够使用它 redefine 进行热更新。

刚好之前也看到一篇文章介绍如何进行 一条龙更新,所以就开始了尝试,先从本地开发测试开始。


选择方案

方案一:jad/mc/redefine线上热更新一条龙

开发时写下的 java 程序是高级语言,需要通过编译生成 .class 文件才能在 jvm 中运行。

所以在一个运行中的程序中进行热更新,需要先将它使用 jad [Java decompile]反编译,修改 .java 文件后使用 mc [Memory complile] 编译出 .class 文件,最后使用 redefine 命令更新虚拟机中的程序。

首先可以跟着教程来一次尝试 https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=arthas-advanced

# 反编译$ jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java# 修改文件$ vim /tmp/UserController.java# 查找加载的 ClassLoader$ $ sc -d *UserController | grep classLoaderHash classLoaderHash   6bc28484# 编译$ mc -c 6bc28484 /tmp/UserController.java -d /tmp# 热更新$ redefine /tmp/com/example/demo/arthas/user/UserController.classredefine success, size: 1
# 反编译$ jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java# 修改文件$ vim /tmp/UserController.java# 查找加载的 ClassLoader$ $ sc -d *UserController | grep classLoaderHash classLoaderHash   6bc28484# 编译$ mc -c 6bc28484 /tmp/UserController.java -d /tmp# 热更新$ redefine /tmp/com/example/demo/arthas/user/UserController.classredefine success, size: 1

跟着教程 demo,发现代码逻辑被修改,返回我修改后的结果,心里在狂喜,可以不用喝这些多咖啡!


实际项目中反编译失败

但在工作中的项目中使用,发现出现了这个问题:反编译后的类不完整

查看通过 jad 命令反编译后的文件:

/* * Decompiled with CFR. * * Could not load the following classes: * .... */

在不完整的文件中进行修改后,进行 mc 命令编译,将会提示如下:

[arthas@7281]$ mc -c 6bc28484 /tmp/xxxx.java -d /tmpMemory compiler error, exception message: Compilation Error......, please check $HOME/logs/arthas/arthas.log for more details.Affect(row-cnt:0) cost in 884 ms.

可以看到,如果有复杂的类,并一定能够成功反编译,遭遇了失败,开始排查原因


反编译失败原因

开源的好处的是,大家可以一起参与到其中,提出问题和解决问题,在 github 项目 arthas 的 issue 中,通过关键字 jad 反编译 找到了原因

横云断岭 Arthas源码分析–jad反编译原理:

可能好巧不巧,实际项目中的代码,就遇上了这 1% 情况(顺便看了其它类,发现这种情况还不少…)

当时对于 jad 机制是有点不了解,所以想先通过上面的提示的工具 dumpclass 去精确获取 java 字节码,但奈何有些难用,尝试了几遍还是没能拿下来,于是开始换种思路。


方案二:直接拿到 .class 文件

既然前面的操作,获取修改后的 .class 文件,都是为了最后一步 redefine 所服务,那只要获取精确的 .class 文件就可以了,跳过前面的步骤也可以。

于是与一个前辈讨论后,他建议我使用 IDEA 工具编译后的 .class 文件

于是将本地代码进行修改,进行打包编译,得到想要的 .class 文件,然后将这个文件上传到测试环境,进行替换。

文件地址类似下图:

[arthas@63]$ redefine /tmp/xxxxxx.classredefine success, size: 1

出现了成功的提示,同时进行了接口测试,发现执行的代码是修改后的逻辑!


总结

通过上面说的,正常来说只需要简单四步就能进行热更新

一、使用 jad 反编译出 .java 文件

二、编辑文件,修改逻辑

三、使用 mc 编译修改后的文件

四、使用 redefine 热更新

当然,也可能遇到 jad 反编译失败的场景,可以参考方案二,直接拿到修改后的 .class 文件,然后继续进行操作。


题外话

标题最后一个字为什么叫【误】呢,是因为我经过测试,跟前辈们讨论后,在发布流程规范、 IDEA 提供的 .class 文件不确定性还有工具误用的把控上考虑,觉得目前不适合使用,于是还是走了正常的发布流程。

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

以后要避免再犯这些小错误,恩,换言之,我喝了很多杯 Java :-(


参考资料

  1. Arthas 用户文档
  2. jad/mc/redefine线上热更新一条龙
  3. 横云断岭 Arthas源码分析–jad反编译原理

进行判断使用class_记一次使用 Arthas 热更新线上代码相关推荐

  1. 蓝的成长记——追逐DBA(3):古董上操作,数据导入导出成了问题

    蓝的成长记--追逐DBA(3):古董上操作,数据导入导出成了问题 ***************************************声明************************** ...

  2. 单片机实验——改进型交通信号灯设计,交通信号系统是保障交通安全高效的重要设施,为了利于司机更好的判断,很多交通信号灯系统在原来的系统基础上设置了倒计时显示器。本实验利用7段数码管作倒计时显示器

    实验内容及要求 交通信号系统是保障交通安全高效的重要设施,为了利于司机更好的判断,很多交通信号灯系统在原来的系统基础上设置了倒计时显示器.本实验利用7段数码管作倒计时显示器,设计一个改进型的交通信号灯 ...

  3. php 判断联通移动电信,JavaScript_JavaScript判断手机号运营商是移动、联通、电信还是其他(代码简单),正则表达式判断所填入号码的 - phpStudy...

    JavaScript判断手机号运营商是移动.联通.电信还是其他(代码简单) 正则表达式判断所填入号码的运营商js代码修改版:/article/31563.htm 在做WEB项目时,有时候需要根据用户的 ...

  4. c语言多组数据判断回文字符串,详解判断回文字符串跟回文数算法的C语言代码...

    详解判断回文字符串和回文数算法的C语言代码! 一.判断一个字符串是否为回文字符串 #include #include #include //包含strlen #define YES 1 #define ...

  5. for循环两个分号之间不要乱加判断条件(记洛谷P2141题WA的经历,Java语言描述)

    题目要求 P2141题目链接 分析 暴力法可解--我们只需遍历一遍数组,在里面再遍历一次,再遍历一次,共三层嵌套,需要保证内层counter数值不能与外面诸层的counter相同~~ 暴力还可防漏,很 ...

  6. 自动判断PC端、手机端跳往不同的域名JS实现代码

    输入相同域名,在pc端和移动端会出现不同的页面效果,一种是用栅格系统实现自适应, 更多的是设计两套不同的模板和两个二级域名或者一个主域名和一个二级域名(就是有区别就可以了); js代码判断浏览器的用户 ...

  7. 智能判断图片中是否存在某物体_如果给猫披上象皮,神经网络将作何判断?

    选自medium,作者:Robert Geirhos,机器之心编译,参与:Geek AI.张倩. 神经网络识别物体依赖的是形状还是其他表征?一直以来,人们普遍认为答案是前者,但本文中的研究者通过实验颠 ...

  8. c语言程序判断一个字符串是否是回文数,详解判断回文字符串和回文数算法的C语言代码!...

    一.判断一个字符串是否为回文字符串 #include #include #include //包含strlen #define YES 1 #define NO  0 #define uchar un ...

  9. UE判断有没有打了勾的材质通道没有给上贴图的

    这其实是一个大需求里的小需求 主要就是判断一个材质球当Channel已经打钩后,是不是已经给上贴图(没给上会显示None) 而如果Channel打勾但是没上贴图这说明美术那里是有一些细节贴图缺失的,这 ...

最新文章

  1. 牛腩44 整合登陆页 RequiredFieldValidator 和 ValidationSummary 以及 asp.net 自带的MD5 加密...
  2. python网络编程证书_《Python网络编程基础》笔记
  3. php保存附件到指定服务器,如何在PHP中将电子邮件附件保存到服务器?
  4. 用Zend Encoder加密PHP文件和PHP 优化配置
  5. CLR via C# 阅读 笔记
  6. org.springframework.data.redis.serializer.SerializationException: Cannot serialize;
  7. 基于centos6.5搭建solr服务器
  8. 【递归算法01】递归的调用机制
  9. 企业管理软件解决方案 出售 :针对华东区中小企业订单仓储管理流程
  10. TensorFlow神经网络(四)手写数字识别
  11. Python面试题解析之网络编程与并发
  12. Treeview动态添加用户控件 取值和传值(第二种样式)
  13. 剑指offer-06-旋转数组的最小数字
  14. 动态系统建模与仿真 基本知识笔记(源自DR_CAN)
  15. cad刷新快捷键_CAD快捷键命令
  16. arm9开发板重新生成文件系统,并烧写
  17. 黑暗城堡(最短路径树)
  18. Tracking-Learning-Detection原理分析
  19. 为何日本手机走不出国门—iFanr版
  20. APP是怎么精确统计下载数量?

热门文章

  1. CEPH快速部署(Centos7+Jewel)
  2. opengl启动过程
  3. 谷歌招聘主管公开八大求职秘诀
  4. 我感到惭愧不已的飞鸽传书
  5. 【原创】技术人员如何去面试?
  6. 飞鸽传书的设计应当具有“完整性”
  7. 从C语言过渡到C++并不容易啊,大家说呢?
  8. 飞秋_飞秋2010_飞秋2010下载_飞秋下载2010正式版
  9. 购买MP3必备资料 各大芯片方案齐齐数
  10. 为MFC应用程序添加全屏幕显示功能