| 導語

支付寶作為國民級應用,當前全球使用者已經超過 10 億,提供了超過 200 項以上的服務,而崩潰率始終維持在萬分之五以下,而且每天支付寶都上線新的功能和改進。做到今天這樣的成績,並不容易,是經過長時間的實踐經驗積累下來的。 支付寶的架構演進主要經歷了三個階段,如果用比喻的話,可以分為獨木舟、戰列艦和航空母艦三個階段。
| 獨木舟時代
-
研發同學晚上提交的可以執行的程式碼,到第二天早上來更新一下就完全不能用,原因是其他不相干團隊提交程式碼覆蓋或者汙染了自己的程式碼。
-
臨近釋出點的時候,通常是最忙的,但不是忙著趕功能,而是忙著解決合併程式碼產生的各種問題,不僅浪費時間,還耽誤測試同學的寶貴時間。
-
即使最後勉強釋出了,穩定性和效能也是非常糟糕的,因為各個模組只管自己的,沒有統一的規範,也缺乏統一的監控。
-
最令 Android 開發頭痛的是 65535 的問題,彼時 Google 還沒有推出 multi-dex 的方案。
| 戰列艦時代
當設計新一代的客戶端架構時,我們從三個方向進行思考:團隊協作、研發效率、效能與穩定。
團隊協作方面,我們希望整個架構分層合理,基礎層面,將通用能力下沉,為更多的上層業務服務,避免重複創造輪子;業務層面,各個業務團隊能夠獨立開發管理,不會對不相關的業務造成影響。基於這個初衷,我們形成了下圖這樣的架構:

整個客戶端架構總共分成四層:業務層、服務層、元件層、框架層。
- 業務層:只需專注於業務邏輯與介面的實現,當需要呼叫如支付這樣的通用能力時,研發同學直接使用下層提供的服務能力,不需自己開發,如此能夠保證核心能力有收口,方便監控。
- 服務層:常用模組,如登入、支付、營銷等,它們不僅自己是業務,也向其他業務提供自己的服務,我們將此類模組歸類到服務層。
- 元件層:這一層提供的是客戶端通用能力,如安全、網路、多媒體、儲存這些,它們提供穩定的介面給上層使用者,同時不斷優化自身內部的效能和穩定性,作為客戶端的基石,它們至關重要。
- 框架層:最為關鍵的部分,包括容器、微應用、服務框架以及 Pipeline,客戶端的微應用化、啟動管理都依賴框架層的運作。
我們將服務層、元件層和框架層合稱為 mPaaS,即移動端上的 PaaS 服務。這些 PaaS 服務可以複用,我們不僅在支付寶裡使用它們,也在其他集團應用,如螞蟻財富、網商銀行等中使用。
我們的解決方案借鑑 OSGi 的概念,將整個客戶端以 Bundle 為單位劃分,每個 Bundle 可以包含自己的程式碼、頁面和資源。讀者可能會想,這究竟和 aar 有什麼分別呢?其實區別很大!
首先,Bundle 裡的程式碼部分是已編譯的 dex,當編譯 apk 時,我們只需要合併 dex 即可,不需要像 aar 那樣將 class 編譯成 dex 再進行合併,這樣大大節省了打包時間;其次,Bundle 是可以獨立執行於自己的 ClassLoader 中的,並且我們可以通過殼代理的方式載入 Activity 等基礎元件,使得動態下發業務成為可能;最後,Bundle 裡還包含微應用、服務和 Pipeline 相關的配置資訊,框架會根據這些資訊啟動相應的元件。

mPaaS 的服務,即 Service 類似於 Spring 框架中的 Service,它對外提供介面服務,而使用者不需要知道如何初始化服務的例項以及生命週期管理,這些完全由框架來託管。使用者只需要知道目標服務介面類的方法引數即可,呼叫時通過框架提供的 API 來獲取例項。
對於服務的釋出者來說,他在自己的 bundle 中宣告介面類以及實現介面類派生的例項類,並註冊相關資訊到 bundle 的 manifest 檔案中。這種做法的本質思想是 Inversion of Control,減少類之間的複雜依賴,避免繁瑣的初始化工作。以依賴介面的方式進行開發,能夠解除服務使用者對服務提供者的依賴,在服務提供者尚未完全開發完成時,使用者可以完全以 mock 的方式來模擬服務,而不需要修改自己的業務程式碼,當然,前提是雙方協商好服務介面的協議。

支付寶中的頁面非常多,直接啟動 Activity 或者 ViewController 對我們來說遠遠不夠,我們選擇在它們上面增加 MicroApp,即微應用的概念。微應用具備唯一的應用 ID,在框架中標識自己的存在。微應用具有統一的入口,根據使用方傳入的字典引數來管理 Activity 或 ViewController。這樣能夠帶來很多好處:
-
只要應用 ID 和引數協議不變,使用方不需擔心目標應用內部重構帶來的影響,直接使用 Activity 或者 ViewController 類名造成的引用氾濫的問題不復存在。
-
微應用的 ID 和字典引數特性,很容易生成 URL,從而實現外部應用使用 URL 跳轉應用內頁面。
-
從資料的角度,我們可以按業務維度來統計使用者行為資料。
-
微應用的概念不僅適用於原生頁面,同樣也適用於 H5 和小程式。註冊為 H5 或者小程式型別的應用 ID,框架會自動將啟動過程 delegate 給 H5 或者小程式容器,而使用者完全不必關心應用 ID 對應的應用型別。
框架層面
-
制定統一開發規範,業務方使用統一的執行緒池、儲存、網路等元件,並按需進行載入,避免不必要的啟動和耗時操作。
-
引入 Pipeline 機制,業務模組如需在應用啟動時進行初始化工作,必須使用 Pipeline。框架依據業務優先順序確定業務初始化實際。
-
利用 AOP 切面,對常用路徑進行耗時統計,追蹤效能瓶頸。
基礎指標
向下突破
| 航母時代
-
只需要一套程式碼,Web 應用可以在 iOS 和 Android 客戶端中執行,能夠相對減少人員的投入。
-
每個使用者日常使用的功能僅僅是支付寶龐大平臺中的一小部分,H5 應用可以做到動態下發,因此可以消除冗餘的儲存,降低包大小。
-
近些年來 React Native,Weex 等動態渲染引擎在社群非常活躍,但經過小範圍的應用以及考慮到 Web 技術的不斷髮展以及其在業界公認的地位,我們最終還是選擇 Web 技術作為動態研發模式的基礎。
-
Web 應用迭代擺脫了客戶端集中時間點發布的束縛,各業務線迭代計劃變得自主可控。
-
前後端分離,我們將頁面資源離線化,這樣節省了資源請求消耗的時間,使得頁面開啟速度提升明顯,解決了在網路環境較差下容易出現白屏的問題。同時,資料請求使用 native 網路通道,可優化的空間更大,安全性更高。
-
差量更新,客戶端更新某業務應用版本時,不需下載完整的新版本資源包,而是下載由釋出平臺根據客戶端本地安裝版本計算生成的體積更小的差量包,這樣不僅能夠節省頻寬和流量,也提升了業務更新的速度。
-
推拉結合,解決業務最新版本覆蓋率的問題,每次釋出新版本時,業務可主動觸發訊息到客戶端,客戶端收到通知後會更新該業務應用版本。同時,客戶端會定時去檢查服務端是否有版本釋出,這樣能夠保證版本釋出後大多數使用者在短時間內獲得最新的應用。
-
容錯補償,客戶端可能由於網路、安全或者儲存許可權等原因,不能使用或者及時獲得離線包,這種情況我們也考慮進來了。我們在釋出離線資源時,釋出平臺會自動生成對應的線上 URL 並配置到應用資訊中,當客戶端載入 Web 應用時發現離線包不可用,會立刻啟用該url載入內容,能夠最大程度保證業務可用性。
-
Android 獨立瀏覽器核心,Android 碎片化的問題自其誕生之初業已存在,而且目前看上去沒有得以解決的跡象。不同系統、不同廠商中的瀏覽器核心同樣存在差異,這導致層出不窮的相容性問題令研發同學頭疼不已,這也違背 Web 一統天下的願景。為了徹底解決並掌控這些問題,我們引入了獨立的 UC 瀏覽器核心並整合在應用中,這樣所有的問題都集中到UC團隊解決,變得非常可控,根據資料統計,使用 UC 瀏覽器核心後瀏覽器相關的閃退和 ANR 有明顯的下降。同時,安全上出現的漏洞,我們可以在第一時間修復併發布,遠比廠商升級更有效率。
-
Web 應用全方位監控,資源載入異常、JS執行異常、白屏、載入耗時等效能資料會被收集上報至後臺,可以及時發現異常。

灰度釋出
實時監控
診斷定位
容災處理
| 啟航出海

關於支付寶移動架構如何演進、如何滿足業務和使用者的需求,這其中還有很多細節和硬貨可以跟讀者分享,這裡因篇幅限制不能夠一一敘述,後續會有更多的相關文章更加深入探討各方面的話題。
往期閱讀
《螞蟻金服 mPaaS 服務端核心元件體系概述:移動 API 閘道器 MGS》
《螞蟻金服 mPaaS 服務端核心元件:億級併發下的移動端到端網路接入架構解析》