云栖大会上宣布即将开源的手淘Atlas什么来头?

在刚刚过去的云栖大会上,手淘宣布其移动容器化框架Atlas将于2017年年初开源,对这个框架,在过去团队对外部做过一些分享,外界也一直对其十分关注,到现在它终于即将开源了。

本文将介绍Atlas的设计思路和手淘对容器化、组件化和动态化上的思考,主要内容来自阿里巴巴资深技术专家倪生华(玄黎)在云栖大会上的分享。

Atlas是什么

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

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

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

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

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

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

目前,Atlas在淘系App的应用十分广泛,手淘自身超过60+业务组件、20个协作团队,以及百万行级别代码都在Atlas上运行,其快速迭代能力让应用的发布周期从每月到每周再到随时发布,在过去半年里就发布了446次。

另外Atlas本身非常轻量,只有90多个类,支持大小型App开发,从大型的手淘到相对小型的阿里健康等都是用的这个框架。其稳定性也接受了考验,兼容Android 4.x以上系统版本。整体手淘的Crash率一直维持在万分之五左右,因为容器导致的crash占比小于百分之一。

从这个意义上来说,Atlas首先要解决的问题是大规模团队的协作问题,诉求包括并行开发、快速迭代、工程解耦,然后解决的问题是客户端动态更新的问题。手淘内部思考的解决方案就是组件化。

Atlas组件化实现

组件化,业界称为插件化,不过这里Atlas的组件化和现在的插件化有一些不一样的地方。组件化是需要去知道组件的功能,设计更规范。

手淘APK包目录结构

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

bundle

从模块来划分,手淘APK可以分为两层,上层是经过拆分的业务Bundle,扫码、评价、详情,各个业务之间可以进行功能的调用,可以通过路由调度到其他业务方。下层是共享的底层中间件,向业务方开放各种能力,如网络库、图片库等,会在容器里进行统一地把控,这样做的好处是包做到尽可能小,第二是性能佳。

分层

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

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

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

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

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

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

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

组件化技术细节

前面讲的是容器层面的比较概要的东西,下面我们会讲一些具体的细节。

关于Bundle的生命周期会提供细粒度的节点,比如下面是一个Bundle从加载到运行的周期:

startInstall:开始加载。这个时候框架会做一些拷贝文件、释放lib、加载Bundle的事情;

Installed:加载完毕。这时框架会注入资源路径,创建class loader;

resolved:解析完毕,框架会检查组件配置是否合法,是否能被解析;

active:运行组件,即开始运行组件Bundle;

started:运行成功。

组件化涉及到的第一个问题是Manifest处理,一个是因为来源很多,有宿主Manifest、Aar Manifest以及组件Manifest,另外不同组件的Manifest经常发生变化,要求我们灵活地去处理。

这里的做法是在工程期将所有的Manifest进行Merge操作,这里需要注意的是Bundle的依赖单独Merge,因为这里涉及到依赖仲裁的问题。最后解析各个Bundle的Merge Manifest,得到整包的BundleInfoList,就是上面我们提到的Bundle信息清单。

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

类加载

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

另外,Dalvik和ART上的资源查找过程顺序是不一样的,加上小米等系统会重写自己的resources,所以我们会适配不同的机型,往后追加AssetsPath或者往前追加,系统AssetManager是个单例,默认往后追加,如果往前追加,则需要重新创建AssetsManager对象,同样主dex动态部署的时候要达到替换原有resource的目的,必须保证插入顺序与查找顺序一致。

还有需要注意的是,每次更新resourceTable的时候,必须保证apkresource,runtime的系统resource,例如webview,bundle resource都已经添加成功,而且唯一,顺序正确。

不同Bundle的资源可能发生命名冲突,我们是用了一种相对来说简单的方法,将各自的Bundle分配成不同的ID,保证所有的业务资源不会产生冲突,尽量将问题放到工程期解决。在很多代码里,通过反射来调用整个资源,在5.0以上的系统是没有问题的,它只找第一个,对业务代码而言,原来是怎么写的,今天还是怎么去写。

关于组件化性能这一部分,我们引入了按需加载,因为手淘APK有70多个Bundle,每个用户真正用的时候只需要5或10个,所以不需要加载所有的Bundle。Bundle之间进行隔离,通过Android四大原生组件进行交互,这样Bundle之间可以比较好的解耦。

我们所有调用的入口都是基于BundleInfolist去做的,根据这个清单信息,得到组件所在Bundle,如果需要加载,我们就进行install、dexopt等操作。

另外,对于解决组件依赖问题,定义了两种新的组件格式Awb(业务Bundle)和solib(so库),前者与AAR一致,不过不添加本地lib,在构建的时候做依赖仲裁区分,后者是Native so库的依赖。Awb其实就是AAR,只是后缀修改了,如果你的包放在宿主Bundle就用AAR,如果是组件Bundle就用Awb。

对于业务Bundle的依赖,我们在构建期会将宿主Bundle和业务Bundle及其依赖分别打包,然后按照最短路径、第一声明原则进行树状仲裁,得到每个Bundle需要的依赖,在打包的时候会将依赖库放到各自的Bundle里去。

依赖

最后是APK构建,我们对它做了比较大的调整。上面的图中,其实左边这一部分是一个标准的APK的构建过程,包括处理,编译,到签名的过程。

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

Atlas动态化

在一个容器框架内,组件化和动态化是相辅相成的,组件只是解决了解耦的问题,但我们如果想要随时发包,就必须让容器框架具备动态化能力。我们在完成了Atlas的组件化之后,做了动态化的支持。动态化的好处一个是包的大小缩减,我们可以将一些包在运行后下载到应用中,另一个是具备动态发版和修复能力。

增量动态化方案

Atlas提供了动态部署的能力,主要目标是动态业务发布,以及问题修复。它基于手淘自研差量算法,主Bundle基于ClassLoader机制,业务Bundle基于差量merge,支持全业务类型。

另外,Atlas也支持Andfix作为插件使用,目标是快速故障修复,它的原理基于Native hook,主要做方法的修改,在实际中可以两个一起用。在工程构建期适配之后,可以做到一套代码两套方案通用。

方案

自研动态部署功能实现原理,首先,对于Dex Patch的生成,我们通过修改Dex的字节码实现,将Dex文件转为Smali,对其中的ClassDef和ClassDataMethod结构体进行分析,可以实现删除、新增、修改类,然后通过Diff处理得到差量文件,再通过Merge处理即生成补丁。

其次是整个资源Patch的生成,分为两块,一个是业务Bundle,本来是一个不断加载的过程,它实现起来会比较简单,通过Md5 diff/BSDiff即可得到。对于主Bundle,因为安卓本身有一个限制,所有的资源必须得在base包里,新增一个资源是不生效的。所以一个做法是在打包的时候预留很多空资源。另外更新已有的资源则通过资源覆盖来完成。

最后,如果新加业务的话,会新加Activity,我们的做法首先在Manifest预埋一个StubActivity,然后在Instrumentation.execStartActivity()阶段进行替换,同时配合Intent setFlag模拟Activity launch mode并继续startActivity,接着System_server进程进行处理,更新ActivityStack,创建binder,并通知ActivityThread进行实例创建,最后我们在ActivityThread的handler里面进行拦截,更新ActivityInfo等信息,创建目标Activity。

另外在工程实践上,因为补丁的生成会涉及到Dex和资源的基线,我们会在部署的时候,每次发布APK包同步发布AP(基线包)到Maven,AP基线包里是所有影响基线的文件,第一是安卓APK,第二是Mapping.txt,最后是Dependency.txt,这样的话整个构建的速度会非常的快。

所以我们这种方式,版本的升级是不同的方式。比如今天手淘的详情要更新,会发布版本,这个版本可能不是到应用市场的版本,而是一个Patch包。业务版本的动态部署,我们是同步的,5.3.0到5.3.1到5.3.2,这样一个好处是只要容器版本没有升级,只要有需求,patch就可以一直升级,而且是无感知的差量升级。

周边优化点

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

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

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

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

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

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

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

时间: 2024-10-05 11:53:41

云栖大会上宣布即将开源的手淘Atlas什么来头?的相关文章

【云栖大会】程序猿、攻城狮的大聚会 他们眼中的云栖大会是啥样

2016年云栖大会进行得如火如荼,"烧脑"."前沿"."高端"."技术"."一票难求"--这些关键词把这场"干货"分享大会衬托得神秘满满,有一群人却沉浸其中,自得其乐. 他们的名字叫--程序猿.攻城狮. 从最初的站长大会,到阿里云开发者大会,再到云栖大会:从200名草根站长到4万名业内外参与者:从单一峰会发展至超过100场论坛的"巨无霸"大会:从纯谈技术到融合音乐节.

【杭州云栖】飞天技术汇大视频专场:全民视频时代下的创新技术之路

摘要: 2018杭州?云栖大会在9月19日如期召开,在四天时间内将举行2场主论坛.170多场前沿峰会.在9月19日上午的飞天技术汇-大视频专场中,多位阿里云技术专家.合作伙伴.客户为现场观众分享了各自领域的多媒体研发成果,进行多款重磅产品的发布,一同解读视频创新技术演进之路. 2018杭州?云栖大会在9月19日如期召开,在四天时间内将举行2场主论坛.170多场前沿峰会.在9月19日上午的飞天技术汇-大视频专场中,多位阿里云技术专家.合作伙伴.客户为现场观众分享了各自领域的多媒体研发成果,进行多款

2016杭州云栖大会新亮点在这里

云栖大会已经圆满落幕,新霸哥近期一直在关注大会的一些情况,相信很多的开发者也在关注大会动态,下面新霸哥将为大家介绍一些关于参加完大会后的一些感想和心得体会和大家分享一下. 云栖大会折射出的是创新.创业大平台.大数据相关产业兴起的一面.2016杭州云栖大会上马云说:新零售.新制造.新金融.新技术.新资源,这五个新将会方方面面的,对各行各业发动巨大的冲击和影响,把握则胜,我不希望把它变成危言耸听的警示,而是当作改变自己的机遇,从现在开始.马总的这番话给我们这些创业者指明前进的方向. “飞天”是科技创

2015年云栖大会:85天盖起来的大会,逾2万人参会,“计算为了无法计算的价值”

[TechWeb报道]10月15日消息,阿里巴巴集团首席技术官王坚今日在2015阿里云栖大会上发表演讲,王坚以三个视角阐述了对阿里云栖大会的理解,他表示:互联网时代计算真正带来的价值和影响是方方面面的. 85天盖起来的大会:阿里云栖究竟是个什么会? 这是一个怎样的会?不仅仅是参会者好奇,阿里内部也很纠结.纠结的原因并非是会议主题的不明确,而是对互联网技术发展变迁的感叹. 王坚指出,“我们不是一个会来讨论大家都知道的东西,这是一个场合,所有人来探索不同的东西.我想今天来参会的人,可能每个人,无论他

云栖大会中你不可以错过的技术盛宴!

2017阿里云杭州云栖大会Clouder Lab探秘 带上电脑去云栖,与专家面对面顺便拿认证!报名9月30日截止! 杭州云栖大会推出的4场Clouder Lab开放实验室,为企业级技术人员提供了一个动手实操的实验平台,帮助他们清晰理解云计算.大数据相关的知识技能,达到即学即用的目的,更可以和阿里云专家一起探索云端最佳技术实践.且课程皆精选自阿里云大学业界首创的Apsara Clouder认证课程. Clouder Lab还将设置现场测试环节,更好的辅助用户掌握核心技能点.通过测试者,可现场领取阿

杭州云栖大会阿里云放大招,8K远程医疗会诊引关注

摘要: 大家每天都会照镜子,镜子里的一切都清清楚楚,足可乱真,可是你想过有一天看视频直播就像照镜子么? 这不,在云栖大会的C馆里,8K超高清直播体验馆前异常火爆,在这里,很多参会者都围着有110寸的屏幕,想要一睹8K超高清画面的风采. 大家每天都会照镜子,镜子里的一切都清清楚楚,足可乱真,可是你想过有一天看视频直播就像照镜子么? 这不,在云栖大会的C馆里,8K超高清直播体验馆前异常火爆,在这里,很多参会者都围着有110寸的屏幕,想要一睹8K超高清画面的风采. 很多人好奇馆中为什么会有一面镜子,仔

我才知道:杭州还有一个叫“云栖小镇”的未来名镇

文/周国辉 “孤山像一片银杏叶,静静地躺在西湖中.”这是发烧友租用直升机从空中俯瞰杭城拍摄的四季美景的解说词,最近在网络上频传,点赞者众. 生活在杭州,因为久处其中,天堂的美似乎也变的习以为常了.这时候,需要善于细细体验,或者换个角度,比如从空中一定距离内观赏,西子湖宛如一颗明珠镶嵌在绿色的大地上,而且随季节的变化而变幻,看了真让人陶醉遐想. 杭州的美丽.隽永不是一成不变的,随着信息网络技术的发展,正在孕育催生新的产业和城市生态,那是流淌着的美. 杭州人都知道有个云栖的地名,那是离九溪不远的一个

广通优云亮相云栖大会呈现火爆现场

10.13日至10.16日由阿里巴巴集团主办的2016年杭州云栖大会在杭州云栖小镇正式拉开帷幕.本届杭州云栖大会以"飞天进化"为主题,内容规模比去年翻倍,广通软件优云展台在期间备受业界关注. 关于优云 "优云"是广通软件(股票号码:833322)旗下的下一代运维品牌,诞生于云计算.大数据和物联网的变革时代,企业同时面临着数字化和"互联网+"转型的双重挑战.优云的混合运维架构融合了双态并存的设计理念,稳态基于ITIL运维实践,保持核心竞争力的稳定:

阿里云在LC3大会上透露未来要做的两件事

摘要: 阿里云研究员褚霸在LC3大会上同多位业界资深大咖同台交流表示,阿里云发展到今天,把过去应对淘宝.天猫大规模计算以及双11的计算能力转换成普惠的能力放在云上,这是一个非常大的挑战,也是其他厂商没有经历过的.这些挑战不断帮助阿里云积累经验,提升技术能力. 6月25日,由LFAsia, LLC主办的全球开源顶级盛会LinuxCon + ContainerCon + CloudOpen(LC3)在北京国家会议中心召开.来自国内外的开发人员.架构师.系统管理员.DevOps专家.商业领袖等数千名专