自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Atlas-手淘組件化框架的前世今生和未來的路

企業(yè)動態(tài)
Atlas是古希臘神話中的天神,是波士頓動力公司的機(jī)器人,借助搜索引擎,得以發(fā)現(xiàn)這個(gè)名詞背后許許多多的含義。

   今天手淘技術(shù)團(tuán)隊(duì)宣布正式開源它們的容器框架Atlas,項(xiàng)目地址:

  https://github.com/alibaba/atlas

  同時(shí)他們還推出了項(xiàng)目官網(wǎng),上線了技術(shù)文檔:

  http://atlas.taobao.org/

  下面讓Atlas團(tuán)隊(duì)來介紹下該項(xiàng)目的歷史、原理和未來。

  

 

  Atlas是什么

  Atlas是古希臘神話中的天神,是波士頓動力公司的機(jī)器人,借助搜索引擎,得以發(fā)現(xiàn)這個(gè)名詞背后許許多多的含義。在手機(jī)淘寶,Atlas是一個(gè)扎根于Android客戶端的一個(gè)組件化容器框架,相比神話中用手和頭支撐起蒼天的泰坦神族,Atlas在手淘默默無聞地承載著手淘上豐富業(yè)務(wù)的運(yùn)行,伴隨著數(shù)不清的功能在用戶手中經(jīng)歷新老交替。

  插件化的歷史

  在阿里,在手機(jī)淘寶,移動客戶端的迭代更新可以說是整個(gè)移動互聯(lián)網(wǎng)從新起到繁榮的見證。伴隨著越來越多業(yè)務(wù)的誕生,越來越多的代碼開始往小小的客戶端涌入,而無論是iOS還是Android,各種客戶端的體積也經(jīng)歷著快速的增長。而由于客戶端的推廣成本較高,各個(gè)業(yè)務(wù)線都有很強(qiáng)的需求接入手機(jī)淘寶客戶端。所以在當(dāng)時(shí)航母戰(zhàn)略的背景下,迫切需要一種技術(shù)能把客戶端化整為零,這些模塊可以自由組合,并且當(dāng)部分功能變更時(shí)只需要更新對應(yīng)模塊。

  我們在2012年底的時(shí)候就開始研究Android上的插件化技術(shù),并與2013年初把Atlas作為插件化框架接入手機(jī)淘寶。基于插件化的能力,一個(gè)普通的Android應(yīng)用可以低成本地轉(zhuǎn)為符合Atlas規(guī)范的插件,使Apk既可以以插件方式運(yùn)行也可以獨(dú)立安裝運(yùn)行。一個(gè)大的Android客戶端項(xiàng)目可以分割成數(shù)個(gè)插件,做到代碼隔離,降低了開發(fā)、維護(hù)、部署的成本。

  

 

  當(dāng)時(shí)插件化的方案可分為三類:Web、WebApp、Native。各種方案在手淘內(nèi)都在有同學(xué)進(jìn)行深入的研究。

  Native形式的插件由于技術(shù)門檻較高,當(dāng)時(shí)業(yè)界采用的并不多見。但是由于其比WebApp有良好的性能和體驗(yàn),同時(shí)對于許多已經(jīng)成型的小客戶端推廣的迫切需求,尤其值得我們?nèi)ヌ剿鳌?/p>

  

 

  上圖是當(dāng)時(shí)插件化的技術(shù)原理的簡圖,其實(shí)跟現(xiàn)在業(yè)界的插件化方案主要的設(shè)計(jì)思路基本一致。Atlas作為一個(gè)模擬的Android運(yùn)行環(huán)境,每個(gè)插件以一個(gè)獨(dú)立的進(jìn)程運(yùn)行在各自的沙箱環(huán)境中。同時(shí)由于接入成本較低,其他的業(yè)務(wù)應(yīng)用基本可以算是零成本的方式接入到手淘環(huán)境,同時(shí)也可以隨時(shí)發(fā)布新的版本進(jìn)行更新。

  插件化的方案有其特有的優(yōu)勢,獨(dú)立的進(jìn)程保證了業(yè)務(wù)的絕對隔離,同時(shí)也便于隔離風(fēng)險(xiǎn)。聚劃算、天貓、彩票一個(gè)個(gè)獨(dú)立應(yīng)用開始起降于手淘這架航母。甜蜜的成長總是短暫,插件化發(fā)展很快,隨著手淘All In方案的深入,一些隱患開始展現(xiàn)。

  性能:新進(jìn)程的開辟極大影響每個(gè)業(yè)務(wù)的進(jìn)入速度,同時(shí)由于手淘的插件并不是用完即走的場景,比如說從首頁->聚劃算->詳情->店鋪->下單各個(gè)環(huán)節(jié)是存在著一定的關(guān)聯(lián),各個(gè)插件的進(jìn)程無法退出。而多進(jìn)程的機(jī)制又極大的占用了內(nèi)存,同時(shí)也引起許多用戶的質(zhì)疑

  復(fù)用:插件的獨(dú)立限制了許多中間件的復(fù)用,AIDL的方式并不適合中間件能力的輸出,獨(dú)立的apk直接進(jìn)入的同時(shí)也攜帶了大量重復(fù)的二方庫,也一方面極大增大的應(yīng)用的體積

  穩(wěn)定:插件化需要一個(gè)模擬的Android運(yùn)行環(huán)境,在Android多版本以及國產(chǎn)ROM的兼容中需要做大量的工作,同時(shí)多插件運(yùn)行過程中在低端設(shè)備上很容易遇到進(jìn)程被回收或者三方應(yīng)用強(qiáng)殺的情況,沒有良好的恢復(fù)機(jī)制會極大降低用戶的體驗(yàn)

  組件化的誕生

  伴隨著All In的進(jìn)行,在手淘內(nèi)部發(fā)起了對大型app進(jìn)行重構(gòu)的計(jì)劃。我們需要這樣一個(gè)框架:

  支持大量豐富業(yè)務(wù)的接入,同時(shí)業(yè)務(wù)之間能夠保持清晰的邊界,各自可以繼續(xù)靈活迭代;

  用一批統(tǒng)一的中間件去支撐起各種業(yè)務(wù)的底層功能,保持中間件代碼的全面復(fù)用;

  能夠盡量保持對系統(tǒng)的低侵入,尊重原生運(yùn)行機(jī)制以降低后期的維護(hù)成本;

  在用戶設(shè)備上盡量體現(xiàn)一個(gè)簡單客戶端的特性,同時(shí)特定的業(yè)務(wù)功能按需獲取,保持體積的可控;

  

 

  ↑新容器化結(jié)構(gòu)設(shè)想↑

  基于對插件化框架對Android運(yùn)行機(jī)制的理解,參考了OSGI在服務(wù)端框架,在開發(fā)IDE等領(lǐng)域"高復(fù)用、低耦合、可插拔"的優(yōu)勢,我們借鑒了OSGI規(guī)范開發(fā)了基于組件化的Atlas容器化框架。

  下圖是基于組件化框架的系統(tǒng)結(jié)構(gòu)

  

 

  最底層的tookit verifier全面羅列了上層需要反射使用的注入和代理的Api,會在應(yīng)用啟動時(shí)先進(jìn)性全局性的校驗(yàn),以避免程序運(yùn)行中遇到不兼容的情況;

  往上Bundle Framework負(fù)責(zé)組件的安裝 更新 操作以及管理所有組件的生命周期,這里組件的邊界隔離就遵循了OSGI的規(guī)范,每個(gè)組件分配獨(dú)立的classloader,同時(shí)組件有各自的資源,每個(gè)資源在構(gòu)建期間由AAPT分配獨(dú)立的package ID;

  Runtime層 主要包括清單管理、版本管理、以及系統(tǒng)代理三大塊:

  版本:每個(gè)組件在構(gòu)建期間就由構(gòu)建插件分配自己的版本號,同時(shí)安裝期間也有各自的版本目錄,每個(gè)bundle的啟動加載都需要經(jīng)過版本的校驗(yàn),組件發(fā)生更新同時(shí)也下發(fā)最新的版本信息。依托版本管理機(jī)制組件的熱更新能力水到渠成。

  清單:OSGI規(guī)范中每個(gè)組件通常通過OSGI.MF來暴露自身的component,這是與Atlas容器所不同的地方。在Android設(shè)備上,多文件的形式很容易受IO異常的影響干擾bundle正常運(yùn)行,所以我們采用了構(gòu)建期間集中生成清單的方式,清單里面記錄bundle所有的component(Android四大組件),依賴、packagename等內(nèi)容。

  代理:各個(gè)系統(tǒng)關(guān)鍵點(diǎn)的注入使得bundle可以做到按需加載,避免了像原生MultiDex方案由于首次啟動時(shí)多dex同步安裝而造成UI卡頓的情況,代理層的核心DelegateClassLoader負(fù)責(zé)類的查找和路由,DelegateResource管理所有bundle的資源,它們在容器啟動時(shí)進(jìn)行注入,并在運(yùn)行過程中隨著bundle的不斷載入進(jìn)行更新。

  接入層 簡單是美-復(fù)雜的東西留給自己。為了方便,Atlas容器有自身獨(dú)立的Application負(fù)責(zé)啟動,同時(shí)在構(gòu)建期間會由插件替換應(yīng)用原有的Application。運(yùn)行期間應(yīng)用首先由AtlasBridgeApplication負(fù)責(zé)啟動,并在容器啟動完畢后全權(quán)代理給應(yīng)用真正的Application;同時(shí)對需要自定義和由外部決策的功能,容器開放接口由接入方簡單設(shè)置。

  解耦和依賴

  依托classloader,組件的獨(dú)立性有了充分的保證,同時(shí)由于BundleClassloader保持了對PatchClassLoader的引用,使得宿主的中間件就如同普通APK開發(fā)一樣可以被組件簡單調(diào)用;同時(shí)組件之間除了基于AIDL的服務(wù)調(diào)用,組件之間提供了靜態(tài)依賴和運(yùn)行時(shí)依賴,相互依賴的組件可以通過配置打成,這在一定程度上使某些偏功能的代碼或者UI的重用成為可能,同時(shí)配置的方式使組件之間的關(guān)系可以清晰追溯。

  

 

  性能的演進(jìn)

  異步按需:由于每個(gè)組件是一個(gè)小型Apk的結(jié)構(gòu),每個(gè)組件安裝使其涉及到文件的拷貝、native lib的解壓以及校驗(yàn)載入等過程。特別是Service等后臺component觸發(fā)組件安裝和前臺Activity引發(fā)組件安裝并行時(shí)UI的流暢很受影響。為了降低對UI的影響,每個(gè)組件的安裝都在一個(gè)統(tǒng)一的異步安裝線程中進(jìn)行。Activity、Service、Receiver等的發(fā)起都被進(jìn)行了異步的處理。

  解釋執(zhí)行組件的代碼在安裝后還需要dexopt才能使用,這一過程在ART上的時(shí)間消耗尤為明顯,為了降低用戶等待時(shí)間,Atlas框架對dalivk系統(tǒng)上首次使用bundle時(shí)關(guān)閉了verify,在ART系統(tǒng)上首次使用時(shí)關(guān)閉了dex2oat走解釋執(zhí)行,保障bundle首次進(jìn)入盡可能地高效,同時(shí)后臺通過異步任務(wù)走原生的dexopt過程,為下次使用做好準(zhǔn)備。

  動態(tài)性的增強(qiáng)

  遠(yuǎn)程組件:插件化時(shí)代的按需下載并沒有被廢棄,獨(dú)立的遠(yuǎn)程組件可以滿足用戶的個(gè)性化需求?;谟脩舻牟僮骱颓鍐螜C(jī)制遠(yuǎn)程組件在用戶需要時(shí)只需要簡單地等待或者授權(quán)就可以從遠(yuǎn)端拉倒本地。同時(shí)當(dāng)用戶設(shè)備因?yàn)榭臻g緊張時(shí)容器也可以清理掉一些長期不用的組件以釋放擁擠的空間

  動態(tài)部署:動態(tài)部署是容器一個(gè)最重要的功能?;诖?,業(yè)務(wù)可以靈活發(fā)布自己的需求;有故障的業(yè)務(wù)可以及時(shí)修復(fù)或者回滾;同時(shí)動態(tài)部署的快速覆蓋能力在灰度等場景下可以更快地收到所需的效果。動態(tài)部署的范圍也通過改造進(jìn)行擴(kuò)大,從最初的組件部署到現(xiàn)在支持除Atlas容器小部分核心代碼外的所有代碼,部署patch包的體積和性能的改進(jìn)也在不斷的進(jìn)行改進(jìn)。

  diff

  每次大版本的發(fā)版,集成平臺會保留該次發(fā)版的AP(Ap中記錄所有參與構(gòu)建的二方庫的版本,組件的依賴,混淆的mapping等各種信息),在手淘接下來每周一次的動態(tài)部署迭代中,動態(tài)部署的構(gòu)建會與之前的dex進(jìn)行字節(jié)碼級別的diff,生成tpatch包,最終下發(fā)到用戶手機(jī)的patch僅包含變化class組成的dex和更改或者新增的資源文件

  Bundle的Merge

  patch收到后,客戶端的merge過程會根據(jù)patch信息,取到source 組件,source dex和patch dex進(jìn)行dex合并,合成新的dex,同時(shí)變化的資源覆蓋老的資源最終形成新的組件。

  

 

  中間件部署

  動態(tài)部署能力的增強(qiáng)少不了對底層中間件的支持,部署的機(jī)制也與bundle截然不同

  1. 中間件代碼部署

  Dalvik和Art在merge過程中都會形成新patch zip,zip中dex以多dex的方式命名,patch dex為classes.dex,原始apk中的classes.dex以此根據(jù)序號+1放入zip中,不同的是dalvik由于preVerify的限制寫入zip中的源dex會先經(jīng)過處理,剔除在patchdex中已有的class,確保被patch的dex無法被打上preVerify的標(biāo)簽。

  安裝過程中則多個(gè)dex依次dexopt,同時(shí)插入到dexpatch的第一位。而ART由于無preVerify校驗(yàn),但是Android到ART后原有的dexopt會改為dex2oat.

  運(yùn)行時(shí)代碼由原來的解釋執(zhí)行改為直接運(yùn)行native代碼,之前的使用過程中發(fā)現(xiàn)單純得往前面追加patch的dex并不能完全解決動態(tài)部署的問題,dex2oat的過程優(yōu)化了class的執(zhí)行代碼,比如說內(nèi)斂,虛函數(shù)的校驗(yàn)等。就有可能在運(yùn)行過程中直接在native層執(zhí)行老的優(yōu)化過的class代碼而不是從新patch的dex中l(wèi)oad新的class去使用。

  所以在ART上類似Dalivk,放入源dex,只是源dex不會做任何處理,然后合并在一起做一遍dex2oat,這樣能使新的class覆蓋老的class參與dex2oat并完成優(yōu)化的過程,

  

 

  2. 中間件資源部署

  資源部署基于overlay機(jī)制達(dá)成,不過dalivk上這個(gè)機(jī)制并不支持新增資源,在overlay的包里面如果讀到了一個(gè)資源,dalvik系統(tǒng)會去校驗(yàn)該資源ID在base中值,如果不存在則拋錯(cuò),所以動態(tài)部署為了利用這一特性同時(shí)支持新增資源的需求,在打基線包的時(shí)候就在每個(gè)不同的type里面預(yù)留了128個(gè)資源ID供后續(xù)動態(tài)部署使用。

  同時(shí)打動態(tài)部署的patch時(shí)會以之前的ID分配的內(nèi)容作為輸入,保證已有的資源分配到的ID保持不變,同時(shí)如果資源沒有發(fā)生變更,則剔除該資源,所以aapt dump resource patch的時(shí)候我們看到的INVALID TYPE 的資源段就表示沒有發(fā)生變更的資源,如果有發(fā)生了變更,且之前有這個(gè)資源,就會在原有的資源ID分配過去,同時(shí)新的資源文件打入patch包或者新的資源文本寫入arsc,如果是新增的資源,則使用預(yù)留的資源段進(jìn)行分配。整個(gè)替換過程如下圖所示

  

 

  Atlas動態(tài)部署的能力隨著手淘的需求不斷進(jìn)行著演進(jìn),隨著整個(gè)框架的開源,自然需求會變得更加廣泛。比如在手淘內(nèi)部一周一發(fā)版的節(jié)奏下,動態(tài)部署對新增component的某些需求并不強(qiáng)烈,而開源后此類功能可能會尤為重要,所以接下來容器的更新迭代中此類的功能也會及時(shí)上線。擁抱開源社區(qū)會是Atlas重新審視自己,繼續(xù)發(fā)展的關(guān)鍵一步。

  未來的路

  相比于iOS,Android的推陳出新的速度是極快的。Google在Android系統(tǒng)的改進(jìn)深入到方方面面,組件化的發(fā)展也需要緊跟Android步伐。

  Atlas起步的時(shí)候MultiDex還未出來,解決方法數(shù)的問題就能帶來足夠的愉悅?,F(xiàn)在Atlas基于組件化減少主dex方法數(shù)的同時(shí),也支持主dex原生MultiDex的能力。目前Atlas內(nèi)部集成了MultiDex的能力,外部只需要打開MultiDex開關(guān)即可。這么做的目的一方面避免外部初始化實(shí)際的誤解,另一方面我們也意識到原生的mulitdex在性能上還有很多優(yōu)化的點(diǎn),我們會在后面及時(shí)進(jìn)行優(yōu)化。

  在開發(fā)調(diào)試方面,Atlas容器框架基于動態(tài)部署的能力支持單個(gè)組件的獨(dú)立編譯調(diào)試,但是相比instantrun的速度,目前還有很大提高。而基于Instant Run改造的單組件秒級編譯也已經(jīng)在緊鑼密鼓的開發(fā)中,后續(xù)基于框架的獨(dú)立調(diào)試插件也將會在Android Studio插件庫中上線。

  Android系統(tǒng)機(jī)制的演進(jìn)也鞭策著動態(tài)部署前行。比如16年Android 7.0的混合編譯當(dāng)時(shí)也給Atlas造成了不小的挑戰(zhàn),服務(wù)于億級的UV,動態(tài)部署的能力的覆蓋面、到達(dá)率都還有進(jìn)一步提升的空間,相比andfix等熱部署修復(fù)方案,動態(tài)部署需要重啟來打到更新的能力可能也需要有新的轉(zhuǎn)變。

  市面上許許多多的容器框架,基本思路就大致兩三種。Atlas本身也沒有特別新的技術(shù),有的是基于已有的知識進(jìn)行不斷的重組和優(yōu)化。在手淘內(nèi)部,追求更高的穩(wěn)定性和性能,億級的UV需要及其穩(wěn)定的容器來承載,同時(shí)Atlas也不斷嘗試新的方案,在創(chuàng)新與實(shí)用之間不斷權(quán)衡。

  Atlas是一個(gè)結(jié)構(gòu)簡明的容器框架,通過盡量簡單的思路去解決移動應(yīng)用從開發(fā)到運(yùn)維中的的桎梏,讓開發(fā)中的復(fù)雜簡單化,讓維護(hù)中的復(fù)雜簡單化,讓開發(fā)從流水線上忙碌的工作回到專注于對最終目標(biāo)的精耕細(xì)作,拋開嘈雜的干擾,撥開虛無縹緲,到達(dá)云和山的彼端!

  掃描下面二維碼直達(dá)Atlas項(xiàng)目官網(wǎng):

  活動推薦:

  

 

  由InfoQ主辦的第二屆GMTC全球移動技術(shù)大會開始報(bào)名了!大會將于6月9-10日在北京舉行。本屆大會,我們將探討智能時(shí)代的大前端,在動態(tài)化、React Native等逐漸流行的現(xiàn)在,移動和前端的融合將會發(fā)生怎樣的變化?點(diǎn)擊閱讀原文進(jìn)入大會官網(wǎng),6折報(bào)名火熱開啟!

責(zé)任編輯:Jane 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2016-10-21 16:17:36

手淘Native框架和思考

2018-08-08 14:37:53

顯卡虛擬化3D

2018-01-31 11:17:59

虛擬化技術(shù)硬件

2010-11-23 17:39:08

Qt

2013-06-17 14:30:56

手游開發(fā)工具CocoStudioCocos2d-x

2024-06-27 10:55:21

2022-09-05 09:01:13

前端模塊化

2011-08-23 09:52:31

CSS

2015-11-18 14:14:11

OPNFVNFV

2025-02-12 11:25:39

2014-07-30 10:55:27

2012-11-01 10:59:38

桌面虛擬化

2016-12-29 13:34:04

阿爾法狗圍棋計(jì)算機(jī)

2013-05-23 16:23:42

Windows Azu微軟公有云

2014-07-15 10:31:07

asyncawait

2021-06-17 07:08:19

Tapablewebpack JavaScript

2012-05-18 16:54:21

FedoraFedora 17

2014-07-21 12:57:25

諾基亞微軟裁員

2016-12-29 18:21:01

2019-06-04 09:00:07

Jenkins X開源開發(fā)人員
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號