作者介紹:古塘,目前主要負責支付寶框架和各個元件通過移動開發平臺 mPaaS 對外輸出工作,今天給大家分享的主題是敏捷開發與動態更新在支付寶 App 內的深度實踐。
活動推薦:CodeDay#1 線下沙龍杭州站已上線,具體活動資訊及報名地址見文章尾部。
支付寶App的架構演進
首先來快速看一下支付寶的架構演進,支付寶在移動端躬耕多年,從簡單的工具型 App 到平臺型、到現在的超級 App。與目前市面上大部分 App 的發展路線類似,目前我們構建平臺的同時,做了更多服務化、模組化的工作。
針對支付寶在超級 App 方面方向下的架構優勢,我們總結了如下特點:
- 多應用的生態:不限於形式,原生模組、離線包、小程式。 開放:底層同一個架構,業務很方便的遷移。
- 動態化:業務可以隨時線上更新,無需發版,隨時響應線上活動,比如雙十一、雙十二,春節掃福等活動
- 高可用、高效能、高靈敏度:完善的監控運維體系、發現問題後多層次的修復技術、客戶端良好的效能啟動體驗,強大的網路效能,防刷抗流量等。
工程化挑戰
從工程化的角度來看,業務和團隊的快速發展也會帶來巨大的挑戰。支付寶的業務量在 15、16 年後有一個指數級的增長,包括團隊人數、模組數量,大家看現在的支付寶也不僅僅是一個簡單的支付工具了,而是包含了各種各樣的業務,服務我們的生活的方方面面。所以我們需要一個靈活開放的架構來支撐多團隊的快速協同開發,需要建立超級 App 的運維體系。
業務複雜性帶來的技術挑戰 下面我們快速看一下業務複雜性會帶來怎樣的技術挑戰,總體來說,分為 4 個方面。
1、基礎能力要求更高:
比如支付寶的核心場景掃碼支付,有更好的識別率和識別速度,push 就是大家聽到的萌妹子語音:“支付寶到賬多少多少元”,這就涉及到要求我們的框架怎麼做保活,怎麼提高推送到達率。 移動安全方面,作為金融級的App,要做到防範黑產,各種羊毛黨。 應急和快速修復方面,這是我們已經提到過的,框架需要快速響應線上問題,並提供相應的修復方案,能做到動態更新,最大程度的保證線上的穩定性。
2&3、效能和環境方面:
隨著業務體量的不斷增大,如果業務同學無腦的把初始化放到啟動過程中,必然會造成啟動時間的不斷增加,在使用過程中,也很容易會產生電量、流量、記憶體、儲存等各種問題,造成線上輿情,網路環境也是一樣,因為現在還在一些偏遠地區可能網路不太好,弱網優化也是需要的,同時我們也需要對千元機、低端機器保持友好,保證低端機的使用者體驗,於是乎,我們急需良好的框架運維機制來支撐業務的快速發展和敏捷釋出
4、多 App 生態
這也正是我們基於 mPaaS 做的對外輸出。支付寶這套框架不止是支付寶自己用,也需要快速賦能我們的合作伙伴,大家都是統一的架構底層,支援業務之間的靈活聯動和快速擴張,這也是前面提到的超級 App 的技術特點。
架構現狀
接下來我們來具體看一下支付App的架構現狀:
從下到上,分別是「容器層、元件層、框架層、服務層和應用層」
- 容器層:最底層的基礎層,管理這每個模組 bundle 的載入和資源的處理,在 Android 上和現在流行的外掛化框架類似
- 元件層:是我們抽離出來的通用元件,提供一些通用能力,比如網路、快取、日誌、影像載入等等
- 框架層:這層和原生的 Android,iOS 系統 SDK 類似,是我們定製的用來做每個模組 bundle 之間解耦、互動和通訊的基礎層,有 Native,H5 和圖上沒提到的小程式
- 服務層:我們基於框架封裝的一些業務服務層,提供登入、支付、LBS 等服務
- 最上面的就是應用層了:即使用者可見的具體業務,對於支付寶來說就是掃碼、轉賬、餘額寶等 所以說支付寶的框架有著明顯的分層結構,除了支付寶本身,螞蟻系內部的 App 也都是依託於此,比如網商銀行、螞蟻財富、口碑等,大家的 App 是底下這 4 層可以做到幾乎一樣,唯一區別就是在應用層搭建不同的業務,而且因為是同樣的架構底層,同一個業務很方便的做多端遷移,比如大家比較喜愛的餘額寶業務在支付寶裡有,在螞蟻財富App 裡也能看到,這套框架也依託於 mPaaS 平臺對外輸出,也歡迎大家體驗。
多種框架支撐
正如剛才所說的,在支付寶內部會有多種框架支撐不同業務的併發開發和快速釋出,大致可分為“Native 開發框架”、“Kylin H5 開發框架”以及“小程式開發框架”,具體的內容我們會在後續展開。
靈活的開發框架
我們認為在支付寶內部開發業務,就像搭積木一樣輕鬆,具有很多特點:靈活性、擴充套件性等等
總體來說,大家都是並行開發,互相不影響,誰的版本有問題,可以隨時回滾到穩定版本:因此積木和積木之間可以做到很好的解耦,之間的互動就是通過前面講到的定製的框架層來通訊,同樣你也很方便地增加一塊新積木,自由擴充套件業務。
OSGI
OSGI 是 Java 做動態化模組化的一系列思想規範,支付寶的框架設計也是借鑑了這個思想。
總體來說,在支付寶內部的每個模組工程我們都稱之為 bundle,在 Android 上的產物其實已經是一個完整的 APK 安裝包了,只不過不能獨立執行,需要依賴底層框架和其他模組,在 iOS 上的產物也是一個具體的二進位制 Framework 包,這樣打最終安裝包的過程其實就是前面提到的把各個積木搭起來的過程,只是二進位制級別的合併,比較耗時的編譯的過程已經分散到各種積木的產生過程中了,這樣做也能大大加快整個安裝包的打包速度。
以支付寶為例,打完整的安裝包包含幾百個 bundle 的,在我這臺 14 年版的 Mac 上耗時也在 1 分鐘之內。
微應用和 service
接下來我們來看看積木和積木之間,業務上是怎樣做互動的。我們通過封裝 MicroApplication 和 service 來實現。
- MicroApplication:我們認為每一個獨立的 bundle 其實就是一個小的 App,所以我們也賦予了和系統 SDK 類似的生命週期代理方法,類似於 iOS 的應用 delegate 和 Android 的 application,通過 AppId 標識,可以隨意跳轉到不同業務的 App,MicroApplication 相關的生命週期事件也會有相應的回撥,不同的 bundle 之間完全不用知道你有什麼 Activity 或者 viewController,只需要告訴我你的 AppId 標識,就可以跳轉過去,就是說框架提供了全域性的路由管理功能。
- Service:這個不同於 Android 上原生的 service 元件,通過框架中介面包的概念思想,很方便的實現對外暴露功能介面,有點類似於單例類的感覺,區別是框架提供了完整的載入和呼叫管理,不用開發自己重複寫單例類造輪子。
Nebula
和市面上流行的 phoneGap (cordova)類似,都是 H5 混合開發解決方案,特點如圖所示:
除了提供基本的 H5 頁面的載入管理、和 Native 做通訊的 JSAPI 機制,還具備一些他們可能不具備的特點
- 1.離線包機制,解決 H5 載入的效能問題
- 2.統一的 UC 核心,解決 Android 上噁心的相容性問題
體驗改善
首先,我們來看H5載入,傳統意義上的H5,在進入的時候上面會有進度條或者轉菊花,體驗會不太好,我們的容器是怎麼解決這個問題的呢?
離線包
離線包是將 HTML、JavaScript、CSS 等頁面內的靜態資源打包到一個壓縮包內,Nebula 使用一套基於 AppId 維度的本地檔案管理方式,對離線包進行管理。這和前面提到的框架「積木的概念」如出一轍,每一個離線包都是一個小積木,這個小積木可以很方便的做到熱插拔,實現動態更新。
小程式
接下來讓我們來看看小程式,看看標題還是很唬人的,面向未來的研發方式。
大家有沒有想過這樣一個問題,為什麼 H5 技術已經發展的相對來說比較成熟了,我們還要推出小程式技術?
因為小程式可以完美解決現在 H5 存在的一些問題:安全、效能、開發效率等各個方面。
- 拿效能舉例,雖然已經有了離線包技術可以大大提升 H5 的載入效能,但是始終渲染出來的還是 H5 頁面,受限於 webView,而小程式就完全不一樣了,最終渲染的頁面,可以是 H5,也可以是 Native 頁面,可以整合 RN、weex 類似的技術,實現原生渲染,而且小程式有自己的框架,可以實現報活、資源預載入等各種優化手段,這些都是 H5 很難辦到的
大家可以看現在支付寶裡的螞蟻森林,搶能量種樹那個,大家應該都玩過吧,當前的版本就是小程式實現,可以體驗一下頁面的載入速度和滑動的效率等等,這已經是一個比較複雜的帶動畫的業務了,都可以做到很好的使用者體驗。
小程式 IDE
同時小程式還有自己的 IDE,幫助開發者能夠實現「編碼實時預覽、自動補全、語法提示」等,從而大大提升了開發效率:
研發流程
因此,基於前面介紹的各種開發框架,這裡可以分享一下支付寶的研發流程,分為「開發、測試、整合釋出」這些過程:
- 開發:建立自己的小積木
- 測試:驗證,通過和不通過
- 釋出:會有釋出經理這個角色,簡單的理解就是最終搭積木的那個人,會審批每個積木到底能不能進最終的大架子,然後再進行各種灰度和釋出流程
高效交付:並行研發流程 + 動態更新
從大版本集中釋出到每個小產品迭代開發,每個小產品線維護自己的小版本,可以控制自己的研發和釋出流程。
打包平臺
內部也會有 CI/CD 打包平臺的支撐,支撐著內部完成「多模組並行開發、業務功能動態部署、線上問題熱修復」。
對於釋出平臺,我們是怎麼做的呢?
- 不同的業務,可以建立不同的釋出任務,可以釋出到不同的版本
- 釋出產物:支援原生的升級包、熱修復包、離線包、小程式
- 釋出型別:內部灰度、外部灰度、正式釋出的維度展開灰度測試?
- 人群過濾:支援不同維度的人群過濾,按白名單、機型、rom 版本等
這裡還可以說一下的是,我們對於離線包這種釋出產物是支援差分機制。舉個例子,我們有一個業務原先是 200K,改個背景邏輯變 210K 了,沒必要因為這 210K 去完整下發覆蓋,通過差分得到補丁。當然,這裡的補丁大小不是 210K-200K 這樣簡單,但至少我們可以通過補丁機制從而達到最大程度地減少資料冗餘,提高整體覆蓋率。
總結:技術架構升級驅動研發方式轉變
總結來說,技術升級驅動研發方式產生轉變,從 Native 為主的研發方式向動態化的研發方式進行轉變:
- 技術選型:原先我們以 Native 為主,少量獨立頁面使用 H5;現在我們更推薦核心元件使用 Native(使用者高頻使用的場景),二級業務儘量使用 H5 或者小程式;
- 釋出方式:目前基於“小步迭代”的選擇,不依賴客戶端釋出點,從而達到隨時釋出的能力;
- 研發效率:目前使用 Web 技術能夠達到更開放的效果,一套 Web 程式碼即可實現跨平臺的能力;
- 安裝包大小:相較於 Native,H5 能夠有效地控制安裝包的大小。
敏捷釋出、保障穩定性
那麼總結一下,支付寶是怎麼敏捷釋出,並保障穩定性的呢?
- 開發測試:通過介面解耦與業務解耦,開發者只需關心自己的業務做好業務迭代和測試,整合之後驗證跑通即可。
- 灰度釋出:提供多方位的灰度策略:白名單、時間窗、應用版本號、系統版本號、手機型號等。
- 監控:監控主要聚焦穩定性的問題,包括“閃退、卡頓、卡死、業務異常”等情況,當問題產生後我們會基於動態修復的手段進行快速修復。相關的埋點監控模組近期也在支付寶開放平臺開放出來,歡迎體驗。
- 動態修復:進行 Native 熱修復和配置下發。具體內容見後續展開。
超級 App 運維體系
因此我們通過釋出、監控、診斷協同作戰,支援體系化運維,形成了所謂的超級 App 運維體系。
接下來我們針對「診斷」展開,前面我們提到的「監控」更多的是發現問題,而如何定位問題發生的原因,是需要通過診斷來進行核驗的。
診斷定位
參考這張圖,我們能夠清晰地瞭解支付寶內部是如何進行問題診斷與定位:從“端到端的資訊打通”到“全鏈路輔助到人”,“詳細資訊拉取”後在進行相應的“診斷分析”,同時會配備具體的診斷策略。
因此,我們可以實現一鍵診斷使用者 App 日誌,具體介面如下:
AndFix
發現問題後,怎麼去修復問題,就要用到一些熱修復的手段了,比如這裡提到的 AndFix。
在 Android 上,AndFix 完全是支付寶同學自研的一套 Android 熱修復技術,15 年的時候已經在 GitHub 上開源。現在 star 數大概有 6000 多個,相信應該有同學也接觸瞭解過,不過開源的版本略老,但是原理不變。
AndFix 可以認為是開創了 Android 熱修復 2 個流派之一的 Native 修復,原理是通過在 Native 端方法指標替換實現,修復的粒度是針對於方法,這樣從原理上來說至少有 2 大好處:
- 1 是補丁包比較小,因為是方法粒度;
- 2 是可以做到實時生效,比較適合修復緊急 bug 這種熱修復場景;
另一種比較流行的技術是通過類載入的機制,因為粒度是類級別,所以補丁包會相對來說大一點,且可能存在 dex 合併的效能損耗,而且因為 Android 虛擬機器沒有類解除安裝機制,所以無法做到實時生效,一定要重啟。
當然,沒有一種技術是萬能的,我們內部也會存在著 dexPatch、instantRun 這種原理的修復技術,應對不同的場景
在 iOS 上,從最早的lua指令碼到大名鼎鼎的 JSPatch,我們內部都會有類似的方案,這個在 iOS 上其實最重要的我覺得不是技術問題,而是蘋果爸爸的政策問題,這裡就不多說了,你懂的。
多層次的修復技術
最後總結一下,一定要有多層次的修復技術,適應不同的業務場景。如圖所示:
移動開發平臺 mPaaS:對外輸出
最後,到了 One More Thing 的時候。前面我們分享所涉及的所有技術手段目前都通過 mPaaS 平臺對外輸出:
「移動分析、訊息推送、熱修復」三款元件近期在支付寶開放平臺上已獨立放出。如果你是移動開發者,且對 mPaaS 感興趣,趕緊上手試用吧:t.cn/ExXJGkP
| mPaaS 第一期線下沙龍 CodeDay#1 開放報名中:
-
活動主題:移動端高效能架構演進與跨平臺開發實踐
本期邀請支付寶移動端技術專家,與大家面對面一同探討在跨平臺開發下的高可用、高效能架構演進與跨平臺開發、動態化更新實踐。
-
報名方式:進入活動頁進行報名;無法到現場的同學可通過釘釘搜尋群號“23124039”立即加入技術交流群,屆時獲取直播地址,並有機會與講師在群內深度交流。
期待你的參與。