听说”双11”是这么解决线上bug的

--Android线上热修复的使用与原理

预备知识和开发环境

Android NDK编程

AndFix浅析

Android线上热修复的原理大同小异。这里仅仅针对眼下最火的框架AndFix进行解说。主要从AndFix的使用原理以及优缺点三个方面进行阐述。

使用方式

介绍

AndFix是一个AndroidApp的在线热补丁框架。

使用此框架,我们可以在不反复发版的情况下,在线改动App中的Bug。AndFix就是 “AndroidHot-Fix”的缩写。

就眼下来说,AndFix支持Android2.3到6.0版本号。而且支持arm与X86系统架构的设备。完美支持Dalvik与ART的Runtime。眼下已经应用到支付宝上。是比較成熟的hot-fix框架。

AndFix 的补丁文件是以.apatch 结尾的文件。(来源:网络)

接入流程图:

接入步骤

1) Maven或Gradle下载aar或直接引入源代码

   

Maven:
<dependency>
    <groupId>com.alipay.euler</groupId>
    <artifactId>andfix</artifactId>
    <version>0.3.1</version>
    <type>aar</type>
</dependency>
Gradle:
dependencies {
    compile 'com.alipay.euler:andfix:[email protected]'
}

2) 初始化PatchManager

patchManager = new PatchManager(context);
patchManager.init(appversion);//current version

3) 载入补丁包

patchManager.loadPatch();

4)存在新补丁包

patchManager.addPatch(path);//path of the patch file that was downloaded

5)删除全部补丁包

patchManager.removeAllPatch();

制作apatch文件

1)  工具 :apkpatch(Github下载)

2)  使用方式

打补丁命令:

usage: apkpatch -f <new> -t <old> -o <output> -k <keystore> -p <***> -a <alias> -e <***>
 -a,--alias <alias>     keystore entry alias.
 -e,--epassword <***>   keystore entry password.
 -f,--from <loc>        new Apk file path.
 -k,--keystore <loc>    keystore path.
 -n,--name <name>       patch name.
 -o,--out <dir>         output dir.
 -p,--kpassword <***>   keystore password.
 -t,--to <loc>          old Apk file path.

合并补丁命令:

usage: apkpatch -m <apatch_path...> -o <output> -k <keystore> -p <***> -a <alias> -e <***>
 -a,--alias <alias>     keystore entry alias.
 -e,--epassword <***>   keystore entry password.
 -k,--keystore <loc>    keystore path.
 -m,--merge <loc...>    path of .apatch files.
 -n,--name <name>       patch name.
 -o,--out <dir>         output dir.
 -p,--kpassword <***>   keystore password.

举例:

两个apk文件,一个有问题,一个把问题攻克了,如图:

打开cmd,cd到apktool所在路径。运行例如以下命令:

  回车,在C:\Users\xiayong\Desktop\HotFixTest\result文件夹下生成例如以下文件

当中,out.apatch便是我们须要的补丁文件。

代码混淆

PS:官方建议使用-applymapping 来打混淆包,保证两次混淆一致。

-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
    native <methods>;
}

疑问

1、.apatch 文件下载下来以后的存储位置应该在哪里?

2、.apatch文件删除了还有效果吗?

3、hot-fix的安全性怎么保证?

带着疑问,请看原理分析~

原理剖析

原理图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

一句话说明:找到问题安装包中出错的Method,用.apatch文件里修复过的Method进行替换。

举个栗子:

演示代码来源:https://github.com/THEONE10211024/HotFixDemo

.apatch文件:

.apatch文件是hot-fix的关键,那么.apatch文件又是一个什么东西呢?以下。我们来重点分析一下.apatch文件。

1.  apatch文件实际上是一个压缩文件

解压apatch文件。一探到底:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

包括了一个dex文件和一个目录。先看看目录里都有什么文件

重点是PATCH.MF文件,用记事本打开。

AndFix首先会读取这个文件中面的东西。保存在Patch类的一个对象里,备用。

再看看classes.dex文件。

用反编译工具反编译后。我们会看到类似例如以下的文件:

分析好了apatch文件,接下来我们一步步看AndFix是怎么修复的。

把AndFix接入自己的APP仅仅须要四行代码:

mPatchManager = new PatchManager(this);
mPatchManager.init("1.0");
mPatchManager.loadPatch();
mPatchManager.addPatch(patchFileString);

1、mPatchManager = new PatchManager(this);

初始化一些以后会使用的对象。(详见代码)

2、mPatchManager.init("1.0");

首先推断传入的版本号号“1.0”是否是已有补丁相应的版本号号。

不是,说明APP版本号已经升级。须要把老版本号的clean掉。然后初始化补丁包:遍历APP的私有文件夹(/data/data/xxx.xxx.xxx/file/apatch)下全部文件,找到以“apatch”为后缀的文件。解析文件->读取文件必要信息(主要是PATCH.MF中)->存放在mPatchs(类型:SortedSet<Patch>)中。

3. mPatchManager.loadPatch();

遍历mPatchs,针对每一个补丁文件:安全校验->解析dex->载入类->找到含有MethodReplace注解的方法->hook替换。

核心的hook替换是调用C++实现的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

Dalvik虚拟机:

Art虚拟机:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

Art虚拟的原理与Dalvik不一样。Art主要是改动“ArtMethod”的属性,让虚拟机“误觉得”改动后的方法即是原来的方法。

以5.0为例:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

优势与亮点

1.      提炼精华,简洁,轻便,适配广。完美的支持了Android 2.3到6.0系统,以及x86框架,机型覆盖率广。提供依据两个apk生成patch的工具,因而使用者仅仅需正向编程,通过工具生成patch文件。下发给client就可以,编程效率高。是完好的、高可用的热修复方案。

2.      与业界其它方案对照:QQ空间、大众点评等採用的是动态载入dex方式。

“后者纯java实现,但须要hack类的优化流程。将打CLASS_ISPREVERIFIED标签的类,去除此标签。以解决类与类引用不在一个dex中的异常问题。

这会放弃dex optimize对启动执行速度的优化。

原则上,这对于方法数没有大到须要multidex的应用。损失更明显。而前者不触犯原有的优化流程,仅仅点杀须要hook的方法,更为纯粹、有效。

不足与缺陷

1.      只支持android 方法的替换,不支持资源文件、xml的修复

2.      慎用android:onClick="showToast"形式的事件注冊。

3.      有人反应和“EventBus”不兼容。(自己測试良好)

4.      有人反应fix之后部分手机出现ANR。(自己遇见过)

集成注意事项

1.      两手准备:一旦发现问题。

1)server下发补丁包;2)server上把有问题的包替换成最新包

2.      注意避免本地多次拉取补丁包。假设x版本号存在y补丁。则不再下载该补丁。

资料链接

1)  google的NDK样例

https://github.com/googlesamples/android-ndk

2)  几个开源热修复或插件化解决方式(排名不分先后)

https://github.com/lzyzsd/AndroidHotFixExamples

https://github.com/simpleton/dalvik_patch

https://github.com/dodola/HotFix

https://github.com/jasonross/Nuwa

https://github.com/alibaba/AndFix

https://github.com/rovo89/Xposed

https://github.com/alibaba/dexposed

https://github.com/bunnyblue/DroidFix

https://github.com/CtripMobile/DynamicAPK

3)  技术原理博客(排名不分先后)

p=781">http://bugly.qq.com/blog/?p=781(QQ空间的解决方式)

https://m.oschina.net/blog/308583(Android Dex分包方案)

http://lirenlong.github.io/hotfix/(浅析xposed、dexposed和AndFix的原理)

http://blog.csdn.net/lmj623565791/article/details/49883661(鸿洋)

http://blog.csdn.net/vipzjyno1/article/details/21039349/(android反编译)

最后。该篇文章所讲的内容我已经以demo的形式放在了github上。须要的朋友请看这里

时间: 2024-08-24 00:58:48

听说”双11”是这么解决线上bug的的相关文章

快速定位iOS线上BUG在哪个控制器崩溃

快速定位iOS线上BUG在哪个控制器崩溃 快速定位iOS线上App崩溃在哪个控制器里面,需要和后台配合使用 下载本项目并添加手动添加到项目里 新建所有的页面都继承于YZViewController 在AppDelegate的didFinishLaunchingWithOptions方法里面写下如下代码: if ([[[NSUserDefaults standardUserDefaults] valueForKey:@"BUG"] isKindOfClass:[NSDictionary

1-1 用本地代码调试线上环境代码

方法1:fillder             第一步:抓包抓取线上代码, 第二步:将远程代码拖到AutoResponder面板 第三步:浏览本地文件 第四步:修改你的文件刷新浏览器,成功,哈哈. 来自为知笔记(Wiz)

MySQL通过添加索引解决线上数据库服务器压力大问题

昨天线上应用反馈晚上 19:30-19:43以及 20:13到20:21两个时间段所有人包括我们自己建的教室都进不去, classroom B套无法登陆,主页无法访问,已有超过10个老师和学生反馈进不去教室的问题 通过监控查看出现问题时数据库服务器的cpu使用率,负载,io,内存使用,swap剩余量等状况,发现数据库当时压力特别大, 数据库连接数: 数据库慢查询也出现很多 查看慢查询日志,发现一个SQL在慢查询日志中频繁出现切执行时间较长 # [email protected]: cms[cms

Android线上bug热修复分析

针对app线上修复技术,目前有好几种解决方案,开源界往往一个方案会有好几种实现.重复的实现会有造轮子之嫌,但分析解决方案在技术上的探索和衍变,这轮子还是值得去推动的 关于Hot Fix技术 Hot Fix技术,简单来说就是针对线上已发布app出现了bug,在不推送新版本的情况下通过发布修复补丁进行修复.通常是刚上线的app,需要快速线上修复bug,类似的技术就叫做热修复或热补丁. 热修复技术能带来什么 让app具有了上线后被修复的可能性,增加事故风险可控性: 避免为修复bug而快速增发新版本,让

【MySQL 线上 BUG 分析】之 多表同字段异常:Column ‘xxx’ in field list is ambiguous

一.生产出错! 今天早上11点左右,我在工作休息之余,撸了一下猫.突然,工作群响了,老大在里面说:APP出错了! 妈啊,这太吓人了,因为只是说了出错,但是没说错误的信息.所以我赶紧到APP上看看. 这果然是出错了,而且还是简单而粗暴的500,太吓人了. 二.本地赶紧调试起来! 既然线上出错了,我们又不能直接进行调试,那当然得马上在本地搞起来了! 1.代码是否有错? 立马启动本地的项目,访问对应的接口,看看是不是代码哪里出错了. 好了,本地的代码和 SQL 都是没错的! 2.SQL 是否有错? 那

解决线上135因mongodb太大容量,导致硬盘空间不足的方法【内部问题解决】

因为不能增加硬盘,不能删除数据.所以采用mount到另外一台机器(137)空间的方法.如下: 1.137上vim /etc/exports 增加:/mnt/data/mongodb 192.168.10.135(rw,no_root_squash) 然后:exportfs -rv 2.mount 137的空间到本地, mount -t nfs -o rw 192.168.10.155:/mnt/data/mongodb /data/mongodb 3.停掉135 mongodb ,kill -2

tomcat 远程debug配置,教你远程调试代码,解决线上故障

IDEA远程DEBUG Tomcat很简单,配置如下: 1.修改tomcat服务器配置 打开tomcat/bin/catalina.sh 在空白处添加如下参数 CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=xxx.xxx.xx.xx:60222,suspend=n,server=y" 说明:address为tomcat服务器ip地址,这里必须填上(如果是局域网ip,就填局域网ip,如果不填ip,可能启动会用12

记一次惨痛的线上bug

讲述背景,刚入职新公司2个月的时候,接手一个红包系统.资历尚浅,对业务也不是很熟悉.公司开发新的平台,需要使用红包功能来进行推广,按照产品的需求,进行开发...然而,问题就出在这里,红包接口比较陈旧,许多代码并有过多注释(甚至多出注释不全,注释出错),接口参数参差不齐,看的很累. 起先,将系统中所有调用红包的地方,都改成调用我的红包系统.和某端联调时,出现各种bug,参数无规约,返回参数不明确,(不知道要返回些啥,无明确需求文档),最后还是某端哥们,将原来的sql提供给我才得以解决此问题. 接着

双11与云计算的前世今生

双11由来 一年一度的双11即将拉开帷幕,剁手党已经准备好了购物车与钱包,准备着一年一度的网购血拼.双11作为一个被造出来的节日,用了6年时间,从最初的淘宝商城促销日,成为了中国特色的电商狂欢节. 阿里CEO张勇曾经阐述过双11的由来: 5年前,那个时候叫淘宝商城,商家也没有这么大规模,当时都不知道有个光棍节,那时张和张的团队最初的想法就是让消费者每年好好玩一次,准备做网上的购物节.2009年,淘宝商城搞'双11',广告营销主打:光棍节(11月11日)没事干,那天就买点啥东西去当礼物送人.为什么