手淘Android容器架构——Atlas的前世今生

手淘Android容器架构——Atlas的前世今生

2018-01-11  白衣  淘宝技术

导语

手淘因其使用的便捷性,越来越成为大家移动购物的首选,尤其是在万众瞩目的双十一等购物节中,经受住了巨大流量的冲击和考验,那么作为如此坚挺的移动购物主流APP,手淘的移动框架是怎样实现功能优化的?

本文将介绍,手淘移动容器化框架Atlas是怎样由来的,有什么样的特性,以及在工程期和运行期是如何工作的?阿里巴巴核心技术团队专家白衣将为您带来精彩的分享。

背景

2013年,手淘航母战略的制定,带来了业务和开发人员的翻倍膨胀。从不到100人猛增四五倍,同时业务数量大增,整个客户端的架构和发版节奏受到极大挑战,Atlas作为之前手淘客户端的基础框架,进行了一次大的重构,形成了今天的Atlas。

一、Atlas容器架构是什么?

Atlas是一个Android客户端容器化框架,主要提供了组件化、动态性、解耦化的支持。支持工程师在工程编码期、Apk运行期以及后续运维修复期的各种问题。

Atlas是工程期和运行期共同起作用的框架,它的特点是尽量将一些工作放到工程期,这样来保证运行期的简单,稳定。

二、Atlas的演变

2012年,Atlas基本成型,那时候是插件化的框架,进程是隔离的。插件和APK完全没有关系,而且是在独立进程里建起来的。随着我们的发展,插件越来越多,进程也越来越多,这就导致一些性能问题,很多东西没有办法复用了。

扫描二维码关注公众号,回复: 1599624 查看本文章

2014年,我们建立了组件式的结构,基本上所有的东西都是在一个进程里运行,一些库都是能够复用的,我们在Atlas容器里做了隔离、控制,那时是静态组件式,只能对拆出去的东西做一些动态更新。

到2015-2016年,我们这时候基本上做到了除个别最前面系统建起来的那几个类不能动态更新外,基本上所有的东西都能够动态更新,就是说能够对Atlas本身做动态升级。

三、Atlas的特性

Atlas容器特性


在工程期,实现工程独立开发,调试的功能,工程模块独立。

在运行期,实现完整的组件生命周期的映射,类隔离等机制。

在运维期,提供快速增量的更新修复能力,快速升级。

Atlas动态特性

支持类型

具有全类型动态能力,支持Class文件,SO和资源的增删改操作

开发透明

对开发者友好,与正常开发功能无差别,自动生成Diff包

成功率

具有非常高的部署成功率和效率

兼容性

兼容性高,适配4.x~7.x~O dp3版本,在线上稳定运行2年多

高性能

通过Verify等手段,达到极小的性能损耗

补丁大小

通过精细化Diff的方法,达到非常小的Patch包


Atlas价值

2013年,手淘基本上每个月发布一次版本, 2014年组件化改造后,一年发了200多次,到2015、2016这两年版本发布的越来越多、越来越快,平均1.7天发布一次。手淘70多个业务、400多个工程师各玩各的,用户几乎是无察觉的,大家会觉得手淘还是这样,但事实上在后台基本每天都有发布的动作。


四、Atlas工程期

Atlas包结构

这是一个手机淘宝的APK包,第一层目录上与标准的APK是完全一样的,在APP会有很多的SO文件,如果解开来看的话,它的结构类似于完整的APK,但本身并不能独立运行,它跟很多插件化的差别是在运行期,它是运行在整个容器里的,每一个组件都是独立的Bundle。

Atlas包构建流程

APK构建,我们对它做了比较大的调整。上面的图中,其实左边这一部分是一个标准的APK的构建过程,包括处理,编译到签名的过程。我们这个不同的地方是多了Awb需要特殊处理,其中Awb的资源根据宿主的resource.ap_和包内资源构建,R文件由Bundle R资源和宿主R资源合并而来,然后我们对Aapt进行了修改,对每个awb分配不同的packageId,然后进行统一混淆,生产各个AWB的Dex,打包为APK,签名之后复制到libs,改名为SO文件,然后合并到taobao APK. 这就是我们组件化的整个过程。


五、Atlas运行期

系统结构



这一块是Atlas的整体设计,分为五层:

第一层我们称之为Hack层,包括OS Hack toolkit & verifier,这里我们对系统能力做一些扩展,然后做一些安全校验。

第二层是Bundle Framework,就是我们的容器基础框架,提供Bundle管理、加载、生命周期、安全等一些最基本的能力。

第三层是运行期管理层,包括清单,我们会把所有的Bundle和它们的能力列在一个清单上,在调用时方便查找;另外是版本管理,会对所有Bundle的版本进行管理;再就是代理,这里就是和业界一些插件化框架机制类似的地方,我们会代理系统的运行环境,让Bundle运行在我们的容器框架上;然后还有调试和监控工具,是为了方便工程期开发调试。

第四层是业务层了,这里我们向业务方暴露了一些接口,如框架生命周期、配置文件、工具库等等。

最上面一层是应用接入层,就是我们的业务代码了。

所以Atlas作为一个框架提供了相对完整的能力,业务层的开发可以在框架生命周期的各个环节做一些自定义的动作,也可以自由的调用系统、框架,乃至其它组件释放的能力。


资源加载


我们会用自己的DelegeteResources替换掉系统的resource,Bundle的资源会逐个在安装的时候添加到AssertPath,由于添加Bundle的顺序非固定,不分区会导致资源查找错乱.


类加载




类加载,这里利用Delegate ClassLoader来动态加载组件的类。Delegate ClassLoader先查找宿主Bundle的PathClassLoader,然后根据前面的BundleList找到对应的BundleClassLoader.


动态部署



1、业务组件动态更新

通过组件Diff,Merge的过程进行更新;直接在组件的生命周期内做,兼容性极好

2、宿主动态更新

通过类、资源、SO文件等的diff算法,通过Merge算法来实现更新,有比较好的兼容性。

3、组件远程下载(从无到有)

在构建期参与构建,在最后发布阶段从APK包中剔除。在用户启动阶段,通过远程下载的方式进行安装。适用于预装、大体积业务等。

六、Atlas周边与开源

最后来讲讲我们的周边优化点,为什么到今天才说要开源,做的过程当中还是遇到了不少问题。

第一点是Bundle的重复资源合并。我们发现,因为宿主问题,必然而然会出现冲突的问题,包括图片资源,我们会放到整个宿主类目中去。

第二是Bundle的依赖校验,以前是代码的话,是编译过的,但因为今天是二进制,这个问题会遗留到现场去,所以会看看API是否会影响Bundle。

第三是类库“瘦身”,因为手淘依赖的各种中间件类库太多了,导致手淘本身很臃肿,方法数很大;所以打包的时候对类库有一个裁剪的过程,优化方法数。

第四是依赖导致的,依赖查询库。

第五是做Dex File等,进行混淆Mapping。

最后是开源准备中,我们在工程期、运行期都会去做开源,并且将机制通过云服务的方式提供出来,阿里百川会提供Atlas的研发支撑能力,包括快捷的生成,发布,回滚,监控等能力。

猜你喜欢

转载自blog.csdn.net/xinzhou201/article/details/79131986