螞蟻金服面對億級併發場景的組件體系設計

5 月 6 日,InfoQ 主辦的QCon 2019 全球軟件開發大會在北京舉行。螞蟻金服技術專家呂丹(凝睇)在大會上做了《螞蟻金服面對億級併發場景的組件體系設計》的分享,我們根據演講整理如下:

今天,我主要想和大家分享一下移動領域基礎組件體系,內容大致可以分爲四大塊,第一塊是標準移動研發所需的基礎服務體系,第二塊是支撐億級併發的核心組件“移動接入”的架構演進過程,第三塊是雙十一、雙十二、新春紅包這種大促活動的的應付方法,最後一塊是目前已經對外輸出的基礎服務產品。

移動研發基礎服務體系

首先介紹一下支付寶客戶端的演進過程。之前,支付寶客戶端的主要功能是轉賬、訂單支付、交易查詢等等,更像是一個工具類的APP,在需要付錢的時候纔會掏出來,用完了就放回去了。2013年,螞蟻金服all in 無線之後,加入了很多服務,例如餘額寶、卡券、探索發現等,基本是把支付寶網站上的功能都儘量遷移到客戶端,支付寶也逐漸演化成一個平臺級別的客戶端。之後,隨着移動互聯網的快速發展,公司內部孵化出了更多的APP,其他行業也在移動互聯網圈內鋪開了大量的業務,爲了提升用戶量、用戶粘性,APP之間也開始進行了大量的業務融合,超級APP也因此而誕生,APP開始朝着生態化的模式發展。

截止到目前爲止,支付寶客戶端的年活躍用戶數超過8億,在大促場景下,同時在線量超過3億,併發請求超過1億,同時上線的用戶數超過百萬每秒。

而在這些數據的背後一定需要一套龐大、複雜、完整的支撐體系來支持支付寶的運作,移動研發基礎服務體系就是其中的重要組成部分。

按照研發過程,我們把移動研發基礎服務體系分成四大塊: APP研發階段,主要包括App框架、基礎組件、雲端服務和研發工具; App測試階段 ,主要包括研發協作平臺和真機測試平臺,其中研發協作平臺包含版本管理、迭代管理、安裝包編譯、構建和打包的能力,而真機測試主要是代替人工服務,減少人工消耗,提升測試效率; App運維階段 ,主要包括智能發佈、日誌回溯、應急管理和動態配置;App運營階段,主要包括輿情反饋、實時分析、離線計算和智能營銷。

螞蟻移動接入架構演進

今天的主題爲支撐億級併發下的基礎服務,而在億級併發下移動接入又是最核心、最重要的一個環節。移動接入並不是單個系統,而是一整套組件的總稱,包括:Spanner+連接管理、API網關、PUSH通知和SYNC數據同步,它是所有移動業務的流量入口,需要維持客戶端的狀態,支持進行統一的管控,同時還需要進行部分的業務數據處理。

其實,一開始並沒有移動接入這個說法,與支付寶客戶端的演進過程類似,後端移動接入也是逐步迭代演進的。最開始,各個業務服務都是自己提供API或者直接暴露能力給客戶端,沒有統一的架構,沒有統一的模型,也沒有統一的管控。

爲了解決這個問題,在all in階段我們引申出了一個API網關,由它來做集中式管理,同時添加了PUSH推送的能力。因爲公司內部有很多APP,我們希望這些能力能夠複用,所以在架構上,我們支持多APP同構,客戶端會提供多個SDK,可以隨時進行集成。

網關架構

上圖是一個移動API網關的架構,從圖中可以看到,我們把API生命週期定義爲以下幾個階段:API定義、API研發、API發佈、API配置、API上線、API運營和API下線。而移動網關又把API生命週期切分成三大塊,分別是研發支撐階段、運行時階段和服務治理階段。

研發支撐階段主要有四個能力,分別爲Code-Gen、API-MAN、API-Test和API-Mock。爲了提高API數據在網絡上的傳輸效率,目前螞蟻的API模型全部都採用了protobuf進行序列化,因此,爲了方便業務開發,API網關提供了統一的基於proto文件的代碼生成工具,並且爲了減少客戶端的文件大小和方法數限制,我們修改了官方提供的生成代碼,有效減少了冗餘的方法並大大減小了客戶端文件大小。

在運行時階段,核心的功能包括API流量管控、數據驗籤、用戶鑑權以及接口系統路由等。

API日常的運維由服務治理體系來搞定,主要的能力爲API監控,並根據實時數據進行API質量模型評估,同時提供了一些應急的管理措施。

API網關最爲核心的架構設計是Pipeline,正如大家所知,網關看起來只是一個簡單的API管控和路由,但其中涉及的節點卻非常多,而每個節點的功能又相互獨立,並且隨着業務的發展,功能節點會逐漸增加,在某些場景下,還需要做不同的節點組合。如果採用傳統的鏈式調用,代碼執行串會非常的長,同時擴展和維護起來都非常的困難。因此我們參考了netty的Pipeline設計,完成了自己的Pipeline鏈路。Pipeline中的各個handler保持相互獨立,同時可以根據需要、根據配置自由捆綁,也爲後續的功能延伸提供了良好的架構支撐;

代碼變革

從代碼來看,我們可以明確的感受到之前的調用過程是一個遠程調用,需要感知路徑、參數等,而在統一了整個數據的交互之後,對於業務系統來說,這個調用過程更像是本地調用,直接調用函數,封裝模型。通過這種方式,業務類研發同學能夠更關注於自己業務系統的代碼邏輯編寫,完全不用關注底層通訊的實現,較大的提升了研發效率。

移動網絡跟有線網絡是有很大區別的。移動網絡比較複雜,用戶狀態也比較複雜,有可能是在地下室、電梯或者其它弱網環境中,並且用戶在移動場景下對於體驗的要求非常高,例如在支付時,用戶需要立馬拿到支付結果。之前,我們主要是做了服務端的改進,針對客戶端並沒有做改進。爲了解決用戶問題、性能問題、提升用戶體驗,我們在進行了一次升級,做了一個統一接入網關,並把它架在基礎組件之上,同時研發了性能數據同步、增強了IP調度等能力。

統一接入網關

統一接入網關(ACCGW),可以理解成一個前置的Nginx,是螞蟻基於Nginx二次開發的一套組件,在內部我們叫做Spanner,它在接入架構中主要負責非業務的那一部分邏輯處理,主要包括SSL的卸載,MMTP的協議解析,數據的壓縮、解壓縮,客戶端TCP長連接的維持,接入流量的總控,數據包的路由以及客戶端日誌的接入。API網關、PUSH推送、數據同步等組件,都在它的庇廕之下。

網絡協議優化

MMTP協議的全稱是螞蟻移動傳輸協議,基於TLV的數據結構,這種數據結構的好處是分包解包的效率非常高,且它是基於二進制的,存儲成本相對較低。同時還滿足了客戶端多個組件的鏈路複用,當然MMTP配合客戶端也有自己的一些特性,同時我們也加入了很多新特性,例如智能連接策略。因爲移動環境下用戶的網絡狀態不是很可靠,如果是傳統的連接方式,不一定能滿足所有RPC請求,所以我們做了策略改進。在能夠使用長連接的情況下儘量使用長連接,如果出現長連接連不上或者閃斷的情況,我們就嘗試使用短連接的方式,短連接可以滿足當時緊急的RPC發數據。同時我們也會用一些併發建連的策略,運營商網絡通常是先連上哪個就使用哪個連接,連接之後我們會使用智能心跳策略,用以捕捉不同運營商、不同地區,對於維持連接的心跳時間的差異。

在併發建連的過程中經常會出現客戶端同時存在多端長連接的現象,數據包可能會在中間做傳輸,如果立馬斷掉的話,數據包就丟了,很可能對業務產生影響,因此我們加入了柔性斷連,以確保可能在傳輸過程中的數據包能被安全送達。另外,多個連接建完之後,客戶端可能出現狀況,服務端沒有及時感知到,無法獲知這個連接是好是壞。因此,我們加入了假連接監測,數據包派發的時候攜帶一個序列號,客戶端回報之後,如果序列號返回了,就證明這個連接是可用的,反之,我們就認爲這個連接是假死狀態,可以在合適的時間點斷掉該連接。

MTLS是螞蟻移動安全傳輸協議,基於TLS1.3。我們在做的時候,TLS1.3還沒有正式發佈,但是我們瞭解到一些它的特性,並將某些特性加入到了設計中。比如採用了1RTT ECDHE的握手方式。1RTT ECDHE是基於ECC加密套件,ECC的最大特點是密鑰串比較小,更小的數據在移動方面有非常大的優勢,例如提升傳輸效率,節省存儲成本。在存儲或傳輸過程中,數據包大小是移動領域特別關注的點。也因爲如此,我們選擇了ZSTD壓縮算法,ZSTD有非常大的壓縮比,且在該壓縮比之下,壓縮和解壓縮的效率都不錯。另外,在某些可支持重放的業務場景中,我們還加入了0RTT策略,第一時間把數據從客戶端發送到服務端。通過上述優化,RPC的平均響應效率提升了5~6倍。

SYNC數據同步

SYNC數據同步聽起來有點陌生,其實可以理解成是PUSH的演進版本。它是基於TCP、雙向傳輸的。雖然傳統的RPC能夠解決絕大多數的問題,但是在某些場景下,它是有缺陷的。例如,客戶端啓動之後,需要通過RPC請求去判斷服務端是不是有數據。其實90%的情況是查詢接口沒有任何的變化或者返回的數據客戶端已經存在了,所以這個過程非常冗餘。除了數據冗餘以外,請求也冗餘,因爲沒有發生變化,調用在原則上是可以省下來的。

當初,在all in之後,我們做了一些體驗上的優化,如預加載能力,當客戶端啓動之後,觸發數據預加載,雖然沒有進入到模塊,但爲了提升用戶體驗,客戶端發送很多RPC請求,也因此造成了大量的冗餘併發請求。

另一個不足是客戶端沒辦法主動感知到服務端的數據變化,比如在聊天場景中,用戶是等着交互的,如果使用RCP定時拉取的方式,客戶端和服務端的成本會非常高,整體響應時間也比較慢。而通過SYNC的推送模式,可以在服務端產生數據的時候,基於TCP方式把數據推送到客戶端,客戶端可以在第一時間拿到數據做業務渲染,比如支付寶的掃碼支付、當面付都是通過SYNC服務來同步的結果數據。

SYNC的基礎核心是——oplog,它類似於mysql的binlog,是每一條增量數據的快照。SYNC會爲每一條oplog生成一個唯一的、遞增的版本號,然後通過記錄客戶端當前數據版本號的方式來計算兩端之間的差量,並僅同步差量數據。因爲SYNC是基於TCP,可雙向主動傳輸,從而達到實時、有序、可靠、增量的數據傳輸效果。同時,SYNC在客戶端觸發場景中,並非基於業務場景,而是基於事件,如建聯、登錄、從後臺到前臺等動作,因此,可以達到單次事件觸發多業務的增量計算,而當無增量數據時客戶端也不需要進行任何的其他RPC請求,從而極大的減少了客戶的請求數和冗餘數據傳輸,不但提高了效率、實時性,還間接的降低了系統壓力。

移動調度中心

對於客戶端請求來說最重要的是在第一時間內找到正確的IP並把請求發出去。之前這些工作一般是由傳統DNS來做,但傳統DNS會有一些問題,例如DNS劫持、DNS解析失敗、不同運營商DNS解析效率不同等等,解析DNS需要消耗額外的RTT。

針對這些情況,我們設立了移動調度中心,它是基於HTTPDNS,並在此基礎上加入了用戶分區信息。什麼叫用戶分區呢?面對億級併發,服務端肯定不會在一個機房裏,可能是在多個機房中,且機房內部還有邏輯分區。用戶屬於哪個邏輯區只有服務端知道,客戶端本身是感知不到的。當某個分區的用戶接入進來後,如果沒有在正確的分區內,且又需要轉到其它分區做業務處理時,如果是採用傳統DNS是無法實現的,因爲無法解析出用戶屬於哪個IP列表。而HTTPDNS+分區數據的模型,可以讓客戶端快速拿到最準確的IP地址,同時客戶端還可以針對這個IP地址做質量檢測和有效性檢測,在請求之前就確定最優的IP地址。另外,HTTPDNS還可以支持海外節點的部署。HTTPDNS一定不會比DNS的效果差,因爲它還有DNS來兜底,一旦HTTPDNS出現問題,那麼就會切換到DNS去做解析。

以上的演進過程滿足了絕大多數日常的需求,但是支付寶有很多大促場景,每次大促的玩法都不同,且峯值集中在一剎那。針對這個場景,我們又孵化出了新的模式,一是API網關的去中心化,二是SYNC-PULL機制,三是SYNC-Bucket計算模式。

網關去中心化

網關去中心化解決的一個核心問題就是成本。大促場景下,業務量不停上升,峯值可能非常高。但峯值只有一剎那,其他時間內機器都是處於空閒狀態,這是非常大的資源浪費。而爲了保證大促時不崩潰,機器又不能減少,所以對應用的壓力是非常大的。

如果都是做單點,那麼還會存在穩定性的問題。如果網關在發佈時出現了某些差錯,那麼有可能影響所有業務流程的處理。另外,如果單個接口出現問題,客戶端出現死循環等問題,也會影響到其他系統業務的流程。面對以上情況,我們把網關去中心化就可以抵消這些風險,如果只是單個系統出問題,那麼不會因爲網絡的問題導致其他業務發生問題。

SYNC-PULL讀擴散

爲什麼會有SYNC-PULL讀擴散的需求呢?因爲支付寶內部有非常多大V商戶,每個商戶有非常多的關注用戶,它需要定期或不定期的做一些運營消息投放。如果按照SYNC的場景,通過寫擴散的方式給每個關注投放一條數據,不僅浪費存儲,而且效率很低下。假設某個商戶有5億關注用戶,5億數據全部入庫最快也要幾十分鐘。另外,由於我們商戶的數量很多,大家都爭搶這個資源,可能會出現排隊的情況。對於商戶來說,無法立馬將活動觸達到用戶端,對於服務端來說,消息可能是一模一樣的,造成了存儲浪費。即使是使用了緩存,整個索引也需要給每個用戶去存一遍,這對數據的TPS依然要求非常高。

爲了解決以上問題,我們升級成了讀擴散的模式,把它抽象成關注關係,每個商戶抽象成Topic,然後把所有數據放在Topic下面。因爲用戶關注的大V相對比較少,且大V生產數據的頻率並不高,有效的數據集不是特別多,所以可以把超級大V的數據先放在緩存裏面,然後通過二叉索引快速尋址用戶下的關注關係,並通過原有的SYNC機制把增量數據推到客戶端。這樣,原來億級的存儲就變成了一條存儲,原來幾十分鐘的響應時間變成了秒級,效率和體驗都有了極大的提升。

早先,我們做SYNC的時候是想讓每個業務都相對獨立、相對隔離,計算也獨立進行。當時的業務場景不多,但是後來接入的業務越來越多,將近有80個業務場景,且每個業務都是獨立計算。客戶端是基於事件的,建連之後,需要進行80次業務獨立計算,在大促一百萬每秒的發送量的情況下,很容易就達到億級,這對數據庫、應用程序、緩存等的壓力都是非常大的,同時這種方式也沒法滿足未來的持續發展。

爲了解決這些問題,我們針對原來的計算特性抽象出了幾個分類。例如,基於用戶維度、基於設備維度、基於一次性、基於多端同步、基於全局用戶配置的幾個大類數據,抽象成幾個抽象模型。我們姑且認爲是有5個bucket,所有的計算都基於bucket方式來做,如果有新的業務加入,那就根據它的特性把它歸到某個bucket中。

另外,大促場景下會有高優先級的業務,所以需要做一些特定的限流策略。針對這種情況,bucket可以動態的增減,業務進出bucket也可以隨時切換。bucket上線之後,當時我們的計算量下降超過了80%,在後面的2、3年中,業務從80個增加到300個,服務器也沒有增加。整體來說,對性能的提升還是非常明顯的。

大促活動場景應對之道

前面的內容主要是移動接入方面的組件設計如何支撐億級場景,下面我們聊一下,如何切實的應對大促活動。

大促活動場景應對之道:步法

通過幾年的大促經驗,我們在技術上提煉出了應對大促的幾個步法:首先業務同學設定業務目標,確定業務玩法;技術同學在收到大促介紹之後,開始分解技術指標,並根據各自系統的能力、流程和特性確定相應的技術方案,確定技術方案的步驟則主要爲:鏈路分析、容量評估、性能優化、流控方案、預案策略以及確定彈性流量規則。在確定完成技術應對方案後,最重要的是進行全鏈路的壓測,通過影子用戶,影子表進行生產環境的全鏈路壓測,每個系統壓測週期短則幾天,長則需要數月。在不斷的壓測中發現問題,發現瓶頸,優化後再次進行壓測,直到完成技術目標;在全鏈路完成壓測指標後,進行多輪活動的演練,以模擬真實業務場景,並驗證技術方案的準確性;此後,根據實際需要,擇時進入大促階段。在這個階段,研發同學主要工作是配合運維進行預案的執行、觀察大促期間各種指標的變化,並根據監控確認是否需要應急。當然,應急方案在之前的演練中也需要進行驗證。隨後大促活動結束後,需要進行預案&應急策略的回滾和驗證,這樣大促活動纔算真正結束。同時,更重要的是,我們需要對每年的大促進行復盤review,以便發現不足,在後續的活動中加以改進。

大促活動場景應對之道——流控

在大促執行過程中,最爲關鍵的是流控。對技術同學來說,讓系統在活動中活下來是對大促最給力的支持,流控是系統最有力的屏障。由於各系統在大促活動中發揮的作用、業務的緊急程度、集羣的規模各不相同,因此大促中一般會犧牲一些特性來爲主要鏈路騰出性能空間,比如流水日誌、壓縮閾值、消息順序性等等。

流量的管控也會分多級,在最上層LVS會在VIP上進行數十億級別的控制,到接入網關層則根據建連量、包數進行億級流控,而API網關層則進行千萬級別的控制。在這幾層上,一般簡單計數即可滿足。而到業務層,特別是中低流量的業務層,一般採取的是令牌桶和分佈式限流方式。然後,在API網關上,也可以做一些自定義的腳本,mock返回結果來爲業務系統抵擋住一部分請求。

自動化真機測試

除了核心鏈路之外,我們也需要一些後勤服務。例如在測試過程中,需要自動化,特別是真機模擬測試來抵消部分的人力勞動。我們的機房中部署了上千臺手機,通常都會進行一些自動化的運維檢測,包括安裝包的安裝卸載、性能損耗、功能測試等。除了自動化測試,它還扮演着自動審批和服務巡檢的角色,分別用來檢測小程序和及時發現問題。通過自動測試平臺可以節省60%以上的重複體力勞動消耗。

客戶端智能發佈——確保客戶端萬無一失

如果要確保客戶端萬無一失,那麼最核心的就是灰度流程,灰度流程結束之後,我們才能發佈到生產環境中。

智能發佈主要支持客戶端各種的發佈包,包括安裝包、離線包、小程序包等。通過多年的發佈,我們也沉澱了一些模板,例如灰度用戶、灰度覆蓋率等等。灰度時我們可以選擇一定的模板,按照既定邏輯,使用自動化流程代替人工處理。

輿情分析——及時獲取用戶反饋

客戶端發佈之後,業務同學一定非常關心用戶心聲和市場反應,技術同學則希望第一時間收集到用戶的真實反饋。輿情分析系統就用來滿足這些需求,輿情繫統可以分爲4大塊:數據採集,主要採集渠道爲各大媒體中心、應用市場評論、開會的反饋功能和客戶滿意中心的數據;數據內容則可以包含各種熱點話題、熱點事件和主要生產問題;數據存儲,目前主要由4大塊來支撐:元數據一般可以採用關係型數據庫,文檔數據使用的是MongoDB,爬蟲採集的條目通過MQ來傳輸,所有數據最終會落至ES中,用來做檢索和基礎分析;數據計算更多的是通過文件算法來對ES中的數據進行分析,最終產出各種趨勢和各種事件、話題排行,同時針對每一個用戶反饋又可以實時通知到相關的負責人。

在這裏我們說的移動分析主要是基於客戶端日誌埋點的數據分析能力。客戶端需要有標準的埋點SDK來採集Native、H5、小程序的各種框架&容器埋點,也需要支持業務自定義的業務埋點。同時,爲了在大促場景能有效的提升服務端性能,埋點的寫入與上報也需要有一些措施來進行動態的控制,埋點在客戶端完成後,在合適的時機就會上報給服務端的移動日誌網關,(移動日誌網關目前也已經逐步被納入到移動接入中進來)。當客戶端日誌上報到服務端之後,即可由日誌網關輸出到服務端日誌文件或投遞至消息組件,供其他的平臺進行消費計算,這包括如Jstorm、kepler、Flink這樣實時計算平臺,也可以投遞到Spark、odps等離線大數據計算平臺來進行進一步分析。作爲基礎組件,移動分析除了日誌採集和同步之外,也進行了一些框架輸出日誌的基本數據分析,行爲分析(像日活、新增、流存在)、頁面分析(停留時長,參與度)、閃退分析、卡頓分析,並提供了日誌回溯和日誌拉取等能力供研發同學進行問題排查和分析。當然,這些數據可以用於各種業務分析,分析的形式完全取決於業務方想如何使用。

對外輸出的基礎服務產品

技術組件產品服務輸出:成熟一個,開放一個

我們的基礎能力經過這幾年的努力,也沉澱了不少技術產品可以輸出出來。這些技術產品覆蓋了從APP研發到測試到運維到運營的各個階段,有客戶端框架、客戶端基礎組件,有云端基礎服務(像API網關、SYNC數據同步、PUSH通知這些),有開放工具,有插件,有伴隨研發測試的研發協作平臺來進行迭代管理、編譯、構建、打包,真機測試平臺,也有APP運維階段所需的智能發佈、日誌管理、應急管理,還有用於APP運營的,各種數據分析和營銷投放產品。這些能力目前已經輸出到了螞蟻國際(印度paytm、馬來西亞、印度尼西亞、菲律賓等)的多個合作伙伴APP,公有云的上百個企業級APP,以及私有云的數十家金融APP。

我們的宗旨是,成熟一個、開放一個,來與合作伙伴共建移動互聯網的生態

一站式研發平臺——mPaaS

爲了能夠幫助合作伙伴快速、有效的建設自己的APP,我們也推出了一站式的移動研發平臺——mPaaS。mPaaS囊括了前面說到的各項基礎能力,同時,支持公有云和私有云,mPaaS不僅僅是技術的輸出,也是生產經驗和運營理念的輸出。

作者簡介:

呂丹(凝睇),2011 年加入支付寶,先後負責了支付寶 Wap、alipass 卡券、SYNC 數據同步等項目,並參與了多次雙十一、雙十二、春節紅包大促活動,在客戶端基礎服務方面有一定的項目實踐經驗與積累。目前負責螞蟻金服移動開發平臺 mPaaS 服務端組件體系優化與架構設計。

活動推薦:

7月12日深圳ArchSummit全球架構師峯會上,ToB的業務逐漸受關注,來自釘釘、騰訊雲、百分點的講師將分享,如何利用互聯網技術攻破傳統企業的銅牆鐵壁,把技術輸出到企業,賦能更多的業務。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章