高可用、彈性動態的金融級移動架構在螞蟻金服的演進之路

| 導語

本文基於重嶽在 2018 年 Arch Summit 北京站的分享內容進行總結,但願經過本篇文章介紹近些年來支付寶在移動端架構的上演進和思考,期冀能給讀者們帶來些許幫助。

支付寶做爲國民級應用,當前全球用戶已經超過 10 億,提供了超過 200 項以上的服務,而崩潰率始終維持在萬分之五如下,並且天天支付寶都上線新的功能和改進。作到今天這樣的成績,並不容易,是通過長時間的實踐經驗積累下來的。 支付寶的架構演進主要經歷了三個階段,若是用比喻的話,能夠分爲獨木舟戰列艦航空母艦三個階段。web

| 獨木舟時代

支付寶剛推出移動端時,它的結構很是之簡單,除了一些工具組件被劃分爲模塊,業務代碼都是糅合在一塊兒。剛開始並無太大問題,可是當咱們的研發人員迅速增加時,問題開始變得棘手起來,僅僅舉幾個例子即可見一斑。
  1. 研發同窗晚上提交的能夠運行的代碼,到次日早上來更新一下就徹底不能用,緣由是其餘不相干團隊提交代碼覆蓋或者污染了本身的代碼。
  2. 臨近發佈點的時候,一般是最忙的,但不是忙着趕功能,而是忙着解決合併代碼產生的各類問題,不只浪費時間,還耽誤測試同窗的寶貴時間。
  3. 即便最後勉強發佈了,穩定性和性能也是很是糟糕的,由於各個模塊只管本身的,沒有統一的規範,也缺少統一的監控。
  4. 最令 Android 開發頭痛的是 65535 的問題,彼時 Google 尚未推出 multi-dex 的方案。
這些嚴重的問題讓咱們的產品研發迭代變得沒法持續下去,所以咱們決定來一次完全的重構,因而步入了戰列艦時代。

| 戰列艦時代

當設計新一代的客戶端架構時,咱們從三個方向進行思考:團隊協做研發效率性能與穩定小程序

團隊協做方面,咱們但願整個架構分層合理,基礎層面,將通用能力下沉,爲更多的上層業務服務,避免重複創造輪子;業務層面,各個業務團隊可以獨立開發管理,不會對不相關的業務形成影響。基於這個初衷,咱們造成了下圖這樣的架構:後端

整個客戶端架構總共分紅四層:業務層服務層組件層框架層瀏覽器

  • 業務層:只需專一於業務邏輯與界面的實現,當須要調用如支付這樣的通用能力時,研發同窗直接使用下層提供的服務能力,不需本身開發,如此可以保證核心能力有收口,方便監控。
  • 服務層:經常使用模塊,如登陸、支付、營銷等,它們不只本身是業務,也向其餘業務提供本身的服務,咱們將此類模塊歸類到服務層。
  • 組件層:這一層提供的是客戶端通用能力,如安全、網絡、多媒體、存儲這些,它們提供穩定的接口給上層使用者,同時不斷優化自身內部的性能和穩定性,做爲客戶端的基石,它們相當重要。
  • 框架層:最爲關鍵的部分,包括容器、微應用、服務框架以及 Pipeline,客戶端的微應用化、啓動管理都依賴框架層的運做。

咱們將服務層、組件層和框架層合稱爲 mPaaS,即移動端上的 PaaS 服務。這些 PaaS 服務能夠複用,咱們不只在支付寶裏使用它們,也在其餘集團應用,如螞蟻財富、網商銀行等中使用。安全

  • 業務分治

要實現業務分治,最好的方式就在代碼上可以進行隔離,你們沒必要在同一個 Codebase 中開發,避免代碼合併衝突的現象,這個一般在 Android 上一般能夠 aar 的方式來實現,可是惋惜的是咱們重構的時候 aar 還沒出來,並且即便有 aar,也存在打包時間隨代碼體積增大線性增加的問題。

咱們的解決方案借鑑 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。這樣可以帶來不少好處:框架

  1. 只要應用 ID 和參數協議不變,使用方不需擔憂目標應用內部重構帶來的影響,直接使用 Activity 或者 ViewController 類名形成的引用氾濫的問題不復存在。
  2. 微應用的 ID 和字典參數特性,很容易生成 URL,從而實現外部應用使用 URL 跳轉應用內頁面。
  3. 從數據的角度,咱們能夠按業務維度來統計用戶行爲數據。
  4. 微應用的概念不只適用於原生頁面,一樣也適用於 H5 和小程序。註冊爲 H5 或者小程序類型的應用 ID,框架會自動將啓動過程 delegate 給 H5 或者小程序容器,而使用者徹底沒必要關心應用 ID 對應的應用類型。
綜上所述,微應用化和服務接口所賦予的特性極大提升團隊間協做效率,各研發小組之間的依賴更加簡單,能夠各行其道,更關注於自身服務的打造建設。
  • 性能優化

咱們一方面在架構上做出重大改變來提升研發效率,另外一方面也在不斷的進行性能優化,改善用戶體驗。咱們主要從三個層面來着手:

框架層面

  1. 制定統一開發規範,業務方使用統一的線程池、存儲、網絡等組件,並按需進行加載,避免沒必要要的啓動和耗時操做。
  2. 引入 Pipeline 機制,業務模塊如需在應用啓動時進行初始化工做,必須使用 Pipeline。框架依據業務優先級肯定業務初始化實際。
  3. 利用 AOP 切面,對經常使用路徑進行耗時統計,追蹤性能瓶頸。

基礎指標

對於經常使用指標,如閃退、ANR、內存、存儲、電量、流量等,進行長期追蹤。咱們可以明確獲悉每一個版本之間這些指標上的差別,並進行採樣分析,定位並解決問題。

向下突破

咱們不只僅在應用層面進行優化,同時也向下探索性能提高的可能性。在這方面,咱們也收穫頗豐,好比在 Android 上某些系統版本,經過在啓動階段禁用 GC 的方式得到 20%~30% 的啓動時間縮減;在 iOS 上,利用系統自己的 Background Fetch 機制提升進程活躍時間,實現應用秒起。

| 航母時代

隨着移動支付的不斷普及,面對海量的用戶和業務需求,高可用、彈性動態成爲支付寶客戶端更爲艱鉅的挑戰。支付寶做爲集支付、金融、生活爲一體的服務平臺,須要可以快速穩定的發佈服務和引入第三方服務,同時對於用戶的反饋和訴求必須可以積極迅速的響應。
  • 動態研發模式

咱們在研發模式上做出改變以業務快速迭代的要求,業務逐步由原生頁面向 Web 混合頁面遷移。原有的研發模式可以很好的知足團隊協做的要求,可是隨着業務規模的不斷增大,代碼量相應膨脹致使安裝包太大,在iOS上一度超過代碼段上限,沒法經過 AppStore 審覈,另外基於集中時間點的迭代發佈,一般是一個月發佈一個版本,遠不能知足業務的更新速度要求。相較於原生應用開發,Web應用的優點很是明顯:
  1. 只須要一套代碼,Web 應用能夠在 iOS 和 Android 客戶端中運行,可以相對減小人員的投入。
  2. 每一個用戶平常使用的功能僅僅是支付寶龐大平臺中的一小部分,H5 應用能夠作到動態下發,所以能夠消除冗餘的存儲,下降包大小。
  3. 近些年來 React Native,Weex 等動態渲染引擎在社區很是活躍,但通過小範圍的應用以及考慮到 Web 技術的不斷髮展以及其在業界公認的地位,咱們最終仍是選擇 Web 技術做爲動態研發模式的基礎。
  4. Web 應用迭代擺脫了客戶端集中時間點發布的束縛,各業務線迭代計劃變得自主可控。
  • 打磨 Web 體驗

儘管 Web 應用優點明顯,但在移動端上的短板也是顯而易見的,它提供的用戶體驗、性能以及能力上的限制與原生應用有至關大的差距。爲了彌補這些差距,咱們作了大量的改進,主要在如下幾個方面:
  1. 先後端分離,咱們將頁面資源離線化,這樣節省了資源請求消耗的時間,使得頁面打開速度提高明顯,解決了在網絡環境較差下容易出現白屏的問題。同時,數據請求使用 native 網絡通道,可優化的空間更大,安全性更高。
  2. 差量更新,客戶端更新某業務應用版本時,不需下載完整的新版本資源包,而是下載由發佈平臺根據客戶端本地安裝版本計算生成的體積更小的差量包,這樣不只可以節省帶寬和流量,也提高了業務更新的速度。
  3. 推拉結合,解決業務最新版本覆蓋率的問題,每次發佈新版本時,業務可主動觸發消息到客戶端,客戶端收到通知後會更新該業務應用版本。同時,客戶端會定時去檢查服務端是否有版本發佈,這樣可以保證版本發佈後大多數用戶在短期內得到最新的應用。
  4. 容錯補償,客戶端可能因爲網絡、安全或者存儲權限等緣由,不能使用或者及時得到離線包,這種狀況咱們也考慮進來了。咱們在發佈離線資源時,發佈平臺會自動生成對應的在線 URL 並配置到應用信息中,當客戶端加載 Web 應用時發現離線包不可用,會馬上啓用該url加載內容,可以最大程度保證業務可用性。
  5. Android 獨立瀏覽器內核,Android 碎片化的問題自其誕生之初業已存在,並且目前看上去沒有得以解決的跡象。不一樣系統、不一樣廠商中的瀏覽器內核一樣存在差別,這致使層出不窮的兼容性問題令研發同窗頭疼不已,這也違背 Web 一統天下的願景。爲了完全解決並掌控這些問題,咱們引入了獨立的 UC 瀏覽器內核並集成在應用中,這樣全部的問題都集中到UC團隊解決,變得很是可控,根據數據統計,使用 UC 瀏覽器內核後瀏覽器相關的閃退和 ANR 有明顯的降低。同時,安全上出現的漏洞,咱們能夠在第一時間修復併發布,遠比廠商升級更有效率。
  6. Web 應用全方位監控,資源加載異常、JS執行異常、白屏、加載耗時等性能數據會被收集上報至後臺,能夠及時發現異常。
  • 小程序

咱們不只自身提供各類各樣的服務,也須要引入第三方服務來服務更多的人羣,以往咱們只能引入簡單的第三方 H5 頁面,它們只能使用支付寶提供的少許功能,並且開發人員能力的差別致使用戶體驗不是很理想。小程序將支付寶的能力全面開放出來,從開發到測試皆有完整的 IDE 等工具鏈支持,同時 DSL 簡單易用,對於第三方來講,可以快速開發上線一款體驗和功能比以往更強大的小程序。

  • 線上高可用保障體系

在支付寶,線上風險是每一個研發人員在業務前必須釐清的事情,評估風險,預防風險,監控風險,風險應急處理方案在上線都要準備好。支付寶線上的高可用保障體系由灰度發佈、實時監控、診判定位和容災恢復四大部分組成。

灰度發佈

灰度發佈是預防風險的有效手段之一,對於客戶端來講,線下測試的再怎麼完備也沒法保證在用戶環境下一切正常,直接發佈至全量用戶是很是危險的操做,在支付寶內部屬於嚴重違規。咱們的發佈平臺提供多種灰度策略,包括白名單灰度、時間窗灰度、百分比灰度、基於機型地域系統等維度的灰度。新版發佈前,優先選取活躍用戶和問題高發的機型進行灰度,灰度期間發現並修復問題,不斷擴大灰度範圍,直到閃退率、卡死率等指標符合發佈標準後再進行全量的發佈。

實時監控

首先,制定各類線上監控指標,包括閃退、卡死、流暢度、流量、內存、存儲以及業務不可用埋點等。
其次,上報策略上閃退、卡死、業務不可用埋點等高優先指標實時上報,第一時間發現異常;數據上報使用獨立的進程,確保不影響主業務邏輯;當處於業務高峯時期,好比春節紅包、雙 11 等大型活動時,咱們可以動態調整上報策略以緩解日誌服務端的壓力。除了自動上傳和週期性上傳策略外,咱們經過下發診斷指令至客戶端去獲取平時用不到但駐留在客戶端的日誌,好比 logcat 日誌。

診判定位

咱們可以根據客戶端上報的各類埋點日誌,完整描繪出用戶的操做路徑,根據這些信息,咱們得以嘗試重現用戶的問題,數據的真實性相對用戶提供的信息更加可靠,能減小錯誤信息產生的干擾。另外,經過診斷指令上傳的 logcat 日誌,可以更加完整的信息,幫助咱們更清晰的定位問題,所以咱們一般都要求研發同窗在寫代碼的過程當中可以多輸出些有用的信息。

容災處理

當故障發生時,第一時間要求是可以止血,避免損失擴大,咱們一般會預置開關到業務邏輯當中,當出現業務大面積異常或資損時,後臺推送業務開關至客戶端中,將業務可以臨時屏蔽下線。
客戶端在啓動階段發生的死鎖、閃退或者主頁異常超過必定閾值,會自動清理應用數據,將應用還原至初始狀態,可以一部分由於數據異常致使的啓動問題。
咱們使用 hotpatch 技術來修復原生代碼,一樣 hotpatch 自己是個有風險的技術,所以也要經歷灰度發佈的階段來逐步驗證線上穩定性,一旦發生因 patch 引發的問題,要馬上回滾 patch。

| 啓航出海

支付寶的移動架構 mPaaS 不只僅在螞蟻金服內部獲得普遍的採用,並且其核心的組件以及背後的研發理念現在已輸出包括廣發銀行、西安銀行、華夏銀行等衆多金融機構,幫助他們打造更具競爭力的移動平臺入口。

關於支付寶移動架構如何演進、如何知足業務和用戶的需求,這其中還有不少細節和硬貨能夠跟讀者分享,這裏因篇幅限制不可以一一敘述,後續會有更多的相關文章更加深刻探討各方面的話題。

往期閱讀

《開篇 | 螞蟻金服 mPaaS 服務端核心組件體系概述》

《螞蟻金服 mPaaS 服務端核心組件體系概述:移動 API 網關 MGS》

《螞蟻金服 mPaaS 服務端核心組件:億級併發下的移動端到端網絡接入架構解析》

《支付寶 App 構建優化解析:經過安裝包重排布優化 Android 端啓動性能》

《支付寶 App 構建優化解析:Android 包大小極致壓縮》

關注咱們公衆號,得到第一手 mPaaS 技術實踐乾貨

QRCode
相關文章
相關標籤/搜索