1. 設為首頁   文化中國網歡迎您~!

          干貨推薦|餓了么app的架構演進之路,你的外賣可不簡單

          引言

          時代演進,技術也隨之發展。到今天,APP已然成為絕大多數互聯網企業用來獲取用戶的核心渠道。與此同時,伴隨著業務量的增長,愈來愈大、愈來愈多的APP也在不斷地、持續地挑戰著每一個移動端研發人員的知識深度.

          而我們的移動端技術人員也在這個不斷接受挑戰的過程中,成就了今天的移動互聯網時代。像外賣、打車、12306這種工具,背后的邏輯其實非常復雜。

          餓了么移動APP就是這樣一個挑戰,多用戶量、多業務量,在接受著更多更挑剔用戶的同時,默默地、不斷地演進著移動端的架構。

          MVC

          我們常說,脫離業務談架構就是純粹的刷流氓。餓了么移動APP的發展也是其業務發展的一面鏡子。

          在餓了么業務發展的早期,移動APP經歷從無到有的階段。為了快速上線搶占市場,傳統移動APP開發的MVC架構成了“短平快”思路的首選:

          MVC架構

          這種架構以層次結構簡單清晰,代碼容易開發而被大多數人所接受。

          在MVC的體系架構中,Controller層負責整個APP中主要邏輯功能的實現;Model層則負責數據結構的描述以及數據持久化的功能;而View層作為展現層負責渲染整個APP的UI。分工清晰,簡潔明了;并且這種系統架構在語言框架層就得到了Apple的支持,所以非常適用于APP的startup開發。

          然后,這種架構在開發的后期會由于其超高耦和性,從而造就龐大Controller層,而這也是一直被人所詬病。最終的MVC都從Model-View-Controller走向了Massive-View-Controller 的終點。

          Module Decoupled

          “短平快”的MVC架構幫助餓了么移動APP快速搶占了市場。而隨著代碼量的不斷增加,臃腫的Controller層也在漸露頭角;而業務上,餓了么移動APP也從單一APP發展為多APP齊頭并進的格局。這時候,如果降低耦合,復用已有模塊成了架構的第一要務。

          架構中,模塊復用的第一要求便是代碼的功能組件化。組件化意味著擁有獨立功能的代碼從系統中進行抽象并剝離,再以“插件”的形式插回原有系統中。這樣剝離出來的功能組件,便可以供其他APP進行使用,從而降低系統中模塊與模塊之間的耦和性;也同時提高了APP之間代碼的復用性。

          餓了么移動對于組件有兩種定義:公有組件和業務組件。公有組件指的是封裝得比較好的一些SDK,包括一些第三方組件和自己內部使用的組件。如iOS中最著名的網絡SDK AFNetworking,Android下OKHttp,都是這類組件的代表。而對于業務組件,則定義為包含了一系列業務功能的整體,例如登錄業務組件,注冊業務組件,即為此類組件的典型代表。

          對于公有組件,餓了么移動采取了版本化的管理方式,而這在iOS和Android平臺上也早有比較成熟的解決方案。例如,對于iOS平臺,CocoaPods基本上成為了代碼組件化管理的標配;在Android平臺上,Gradle也是非常成熟和穩健的方案。采用以上管理工具的另一個原因在于,對企業開發而言,代碼也是一種商業機密。基于保密性的目的,支持內網搭建私有服務器成為了必需。以上的管理工具都能夠很好地支持這些操作。

          對于業務的組件化,我們采取了業務模塊注冊機制的方式來達到解耦合的目的。每個業務模塊對外提供相應的業務接口,同時在系統啟動的時候向Excalibur系統注冊自己模塊的Scheme(Excalibur是餓了么移動用來保存Scheme與模塊之間映射的系統,同時能根據Scheme進行Class反射返回)。

          當其他業務模塊對該業務模塊有依賴時,從Excalibur系統中獲取相關實例,并調用相應接口來實現調用,從而實現了業務模塊之間的解耦目的。

          而在業務組件,即業務模塊的內部,則可以根據不同開發人員的偏好,來實現不同的代碼架構。如現在討論得比較火的MVVM, MVP等,都可以在模塊內部進行而不影響整體系統架構。

          這時候的架構看起來更像是這樣:

          EMC架構


          這種E(Excalibur)M(Modules)C(Common)架構以高內聚、低耦合為主要的特點,以面向接口編程為出發點,降低了模塊與模塊之間的聯系。

          該架構的另外一大好處則在于解決了不同系統版本的兼容性問題。這里舉iOS平臺下的WebView作為例子來進行說明。Apple從iOS8系統開始提供了一套更好的Web支持框架——WebKit,但在iOS7系統下卻無法兼容,從而導致Crash。

          使用此類架構,可以在iOS7系統下仍然注冊使用傳統的WebView來渲染網頁,而在iOS8及其以上系統注冊WebKit來作為渲染網頁的內核。即避免了Apple嚴格的審核機制,又達到了動態加載的目的。

          3 Hybrid

          移動APP的開發有兩種不同的路線,Native APP和Web APP。這兩種路線的區別類似于PC時代開發應用程序時的C/S架構和 B/S架構。

          以上我們談到的都屬于典型的Native APP,即所有的程序都由本地組件渲染完成。這類APP優點是顯而易見的,渲染速度快、用戶體驗好;缺點同時也十分突出:出現了錯誤一定要等待下一次用戶進行APP更新才能夠修復。

          Web APP的優點恰好就是Native APP的缺點所在,其頁面全部采用H5撰寫并存放在服務器端。每次進行頁面渲染時都從服務器請求最新的頁面。一旦頁面有錯誤服務器端進行更新便能立刻解決。不過其弊端也容易窺見:每次頁面都需要請求服務器,造成渲染時等待時間過長,從而導致的用戶體驗不夠完美,并且性能上較Native APP慢了1-2個數量級;與此同時還會導致更多的用戶流量消耗。

          另一個缺點則在于,Web APP在移動端上調用本地的硬件設備存在一定的不便。不過這些弊端也都有相應的解決方案,如PhoneGap將網頁提前打包在本地以減少網絡的請求時間;同時也提供一系列的插件來訪問本地的硬件設備。然而,盡管如此,其渲染速度上還是會稍微存在一定的差距。

          Hybrid APP則是綜合了二者優缺點的解決方案。餓了么移動對于此二類APP的觀點在于,純粹展示性的模塊會更適合使用Web頁面來達到渲染的目的;而更多的數據操作性、動畫渲染性的模塊則更適合采用Native的方式。

          基于之前的EMC架構,我們將部分模塊重新進行了架構:

          Hybrid-EMC架構

          Hybrid-EMC架構中,Web作為一個子模塊,注冊加入到整個系統中,從而實現讓業務上需要快速迭代的模塊達到實時更新的效果。

          React-Native & Hot Patch

          經過這些年的業務發展,Hybrid提供的展示界面更新方案也逐漸地無法滿足APP更新迭代的需要。因此越來越多的動態部署的方案被提了出來,比如iOS下的JSPatch, waxPatch,Android下的Dexpose,AndFix, ClassLoader,都是比較成熟Hot Patch動態部署解決方案。這些方案的思路都是通過下載遠程服務器的代碼來動態更新本地的代碼行為。

          React-Native則屬于另一種動態部署的方案,其核心原理在于通過JavaScript來調用本地組件進行界面的渲染。

          而餓了么移動APP發展到今天,各個APP綜合用戶量已經過億。因此一個非常小的Bug所帶來的問題都可能會直接影響到幾萬人的使用。為了保證APP的穩定性和健壯性,Hot Patch方案也就成了當下最有待解決的問題。

          根據80%的用戶訪問20%頁面這一80/20原則,保證這20%訪問最頻繁的頁面的穩定性就是保證了80%的APP的穩定性。因此,餓了么移動對于部分訪問最頻繁的模塊進行了React-Native備份。當這部分頁面出現問題時,APP可以通過服務器的配置,自動切換成React-Native的備份頁面;而與此同時開發人員開發一個小而精的Hot Patch來修復出現的問題。當Hot Patch完成修補后,再切換回Native APP的原生功能。

          這時候的架構看起來會像是這樣:

          HotPatch-EMC架構


          HotPatch-EMC的架構主要目標在于解決移動APP的穩定性問題。通過RN與Native的主備,可以減少系統APP出錯帶來的失誤成本。

          結語

          我們都知道,對于軟件工程來說,這世上沒有銀彈。對于架構而言其實也非常的適用。業務的不斷更新,帶來了餓了么移動APP架構的不斷演進。

          架構沒有真正的好壞之分,只要適用于自己的業務,就是好的架構!

          不過話說,餓了么和美團到底誰更受歡迎?

          推薦閱讀:硬盤作用是什么
          好运来 www.024baiban.com:堆龙德庆县| www.leonardhaleyelectric.com:乐都县| www.mftdq.com:宜川县| www.liuxiaozhou.com:长丰县| www.tinytoonkidswear.com:西丰县| www.wrennak.com:金寨县| www.fengxiangfa.com:东山县| www.world-anime.com:临武县| www.sonda16mn.com:灵宝市| www.borscon-de4.com:武宁县| www.mayaramegiolaro.com:化州市| www.zzliyu.com:灌云县| www.wisengineering.org:白山市| www.jgdzj.com:门头沟区| www.zendiko.com:清水县| www.acdnq.com:临清市| www.madisonkungfu.com:兴城市| www.tztdkyj.com:郎溪县| www.yumaoziyuan.com:璧山县| www.cash618.com:贡山| www.massage-to-heal.com:丹阳市| www.chadathaihouse.com:始兴县| www.testsite03.com:小金县| www.f3n3.com:水城县| www.anapanasatiyoga.net:汕头市| www.hg01678.com:沈丘县| www.akaeno.com:鹤壁市| www.glviagragtr.com:成安县| www.khxrw.cn:宁武县| www.jinshayule53.com:寿宁县| www.bleedingblack.com:白山市| www.bmwbursa.com:台前县| www.curso-endodoncia.com:塔城市| www.3hjapanese.com:广东省| www.kdjbw.cn:哈巴河县| www.emlakdukkaniist.com:通化县| www.droid-factory.com:五莲县| www.jkhly.com:江孜县| www.zxphy.com:遂昌县| www.snrtyre.com:莱阳市| www.mersta.com:威海市| www.provenzabanquetes.com:老河口市| www.inside-economics.com:西乡县| www.dawntoner.com:汽车| www.f7565.com:博野县| www.guanglistone.com:宁陕县| www.565783.com:新密市| www.szqtouch.com:宜黄县| www.21wangmi.com:巴东县| www.kingswatt.com:平阳县| www.xwjweb.com:永仁县| www.vermord.com:井冈山市| www.christoph-behrmann.com:巴彦淖尔市| www.njaoyang.com:瓦房店市| www.aulahumax.com:比如县| www.htjfbjlaw.com:财经| www.xuenaruipet.com:新郑市| www.zhiyitwp.com:阳西县| www.hg43678.com:佛坪县| www.fjgwg.com:错那县| www.uearbitrage.com:晋城| www.aashbooksplus.com:公安县| www.shnanxiang.com:双桥区| www.continue1.com:定结县| www.cnsc-cts.com:雅江县| www.omin-sh.com:淳化县| www.ps3usbjailbreak.com:清原| www.plasticdaisy.net:蓬安县| www.hornyhomepages.com:德安县| www.spoiledrottencatsociety.com:灌南县| www.ox6o.com:醴陵市| www.imageislife.com:郎溪县| www.photolockr.com:永平县| www.taifengdianqi.com:桓台县| www.name-com.com:会东县| www.chinese-india.com:股票| www.zjmetong.com:酉阳| www.asklow.com:手游| www.bazardasminas.net:新昌县| www.torrezanefelipe.com:义马市| www.hooterspanama.com:来宾市| www.rq6.net:太保市| www.photo-vs.com:龙门县| www.cursosrioja.com:揭西县|