本文爲《螞蟻金服 Service Mesh 大規模落地系列》第二篇,該系列將會從核心、RPC、消息、無線網關、控制面、安全、運維、測試等模塊對 Service Mesh 雙十一大規模落地實踐進行詳細解析。文末包含往期系列文章。html
Service Mesh 做爲螞蟻金服向下一代雲原生架構演進的核心基礎設施,在2019年獲得了大規模的應用與落地,截止目前,螞蟻金服的 Service Mesh 數據平面 MOSN 已接入應用數百個,接入容器數量達數十萬,一舉成爲全世界最大的 Service Mesh 集羣。同時,在剛剛結束的雙十一大促中,Service Mesh 的表現也十分亮眼,RPC 峯值 QPS 達到了幾千萬,消息峯值 TPS 達到了幾百萬,且引入 Service Mesh 後的平均 RT 增加幅度控制在 0.2 ms 之內。git
本文做爲整個 Service Mesh 系列文章的消息篇,做者:劉翔(花名:無勤),螞蟻金服消息 Mesh 負責人, 消息中間件核心研發成員,專一於高吞吐、低延遲的消息中間件研發,以及雲原生時代下一代消息系統的架構設計與研發。本文將從如下幾個方面對消息 Mesh 進行解讀:github
Service Mesh 做爲雲原生場景下微服務架構的基礎設施(輕量級的網絡代理),正受到愈來愈多的關注。Service Mesh 不只負責在微服務架構的複雜拓撲中可靠地傳遞請求,也將限流、熔斷、監控、鏈路追蹤、服務發現、負載均衡、異常處理等與業務邏輯無關的流量控制或服務治理行爲下沉,讓應用程序能更好地關注自身業務邏輯。緩存
微服務架構中的通訊模式其實是多種多樣的,既包含同步的請求調用,也包含異步的消息/事件驅動,然而流行的 Service Mesh 實現(Istio,Linkerd,Consul Connect等),都仍侷限在對微服務中同步請求調用的關注,卻沒法管理和追蹤異步消息流量。而消息 Mesh 則是對這一塊的重要補充,經過將消息 Mesh 有機地融合到 Service Mesh 中,能夠幫助 Service Mesh 實現對全部微服務流量的管控和追蹤,從而進一步完善其架構目標。安全
在傳統的消息中間件領域,咱們更關注的是消息服務端的性能、服務可用性、數據可靠性等核心指標,而與業務應用密切相關的一些能力,包括消息的流量控制(限流、熔斷、灰度、着色、分組等),消息的服務治理(消息量級與消息應用拓撲等),消息鏈路的追蹤(消息軌跡)卻每每不盡如人意。網絡
這不只是由於傳統模式下上述能力的提供和優化都涉及客戶端的改造與大規模升級,整個過程經常比較漫長,難以快速根據有效反饋不斷優化,更重要的是缺少一個統一的架構指導思想,混亂無序地向客戶端疊加相關功能只會讓消息客戶端變得愈來愈臃腫和難以維護,也變向增長了業務系統的接入、調試和排查問題的成本。而消息 Mesh 做爲 Service Mesh 的補充,能顯著帶來以下價值和收益:架構
在螞蟻金服內部,Msgbroker 基於推模型提供高可靠、高實時、事務消息、header 訂閱等特性,幫助核心鏈路進行異步解耦,提高業務的可擴展能力,並前後伴隨螞蟻金服衆多核心繫統一塊兒經歷了分佈式改造、單元化改造與彈性改造,目前主要承載螞蟻內部交易、帳務、會員、消費記錄等核心在線業務的異步消息流量。併發
因爲 Service Mesh 的推動目標也是優先覆蓋交易支付等核心鏈路,爲在線業務賦能,所以咱們優先選擇對 Msgbroker 系統進行 Mesh 化改造。下面將以 Msgbroker 爲例,重點剖析 Mesh 化後在總體架構和核心交互流程上的變化,爲消息領域的 Mesh 化改造提供參考。負載均衡
消息 Mesh 化後的總體架構如上圖所示,與原有的消息架構相比,主要的變化有:less
當 Sidecar 代理了消息客戶端的全部請求後,一旦 Sidecar 完成消息服務的發現與服務端/客戶端路由數據的緩存,不管是客戶端的發消息請求仍是服務端的推消息請求,都能由 Sidecar 進行正確的代理轉發,而這一切的關鍵,則是 Sidecar 與消息客戶端協同完成一系列的初始化操做。
消息 Mesh 化後具體的初始化流程以下所示,與原有的初始化流程相對比,主要有以下不一樣:
MOSN:https://github.com/sofastack/sofa-mosn
消息中間件最關鍵的挑戰,在於如何在洪峯流量下依然保障消息服務的高可靠與高實時。而在消息 Mesh 化的大規模實施過程當中,還須要考慮數十萬的容器節點對數據面總體穩定性和控制面性能帶來的巨大挑戰,這些都依賴於完善的 Sidecar 運維體系,包括 Sidecar 的資源分配策略,以及 Sidecar 獨立變動升級的策略。
當 Service Mesh 的實體 MOSN 做爲 Sidecar 與業務容器部署在一塊兒時,就再也不像消息服務端同樣只須要關心自身的資源消耗,而是必須精細化其 CPU、內存等資源的分配,才能達到與應用最優的協同合做方式。在 Sidecar 的精細化資源管理上,前後經歷了獨立分配、經過超賣與業務容器共享、細粒度的 CPU 資源分配策略和內存 OOM 策略調整等多個階段,最終基於 Service Mesh 將原有的與業務無關的邏輯下沉到 Sidecar,其佔用的資源實際是原來業務容器會使用的資源這一假設,在零新增成本的狀況下平穩支撐了數十萬規模級別的 Sidecar 容器分配。關於資源管理更詳細的內容能夠期待後續 Service Mesh 系列文章中的運維篇,本文就再也不贅述。
爲了達到 Sidecar 這一類基礎設施的變動升級對業務徹底無感知的目的,就須要使 MOSN 具有平滑升級的能力。在平滑升級過程當中,新的 MOSN 首先會被注入,並經過共享卷的 UnixSocket 去檢查是否存在老的 MOSN,若存在,則利用內核 Socket 的遷移實現老 MOSN 的鏈接所有遷移給新 MOSN,以下圖所示,最終再讓老 MOSN 優雅退出,從而實現 MOSN 在整個升級和發佈過程當中對業務無任何打擾,關於 MOSN 自己平滑升級更多的內容,能夠參考 Service Mesh 系列文章中的核心篇。
上述平滑升級方案,其實隱含了一個很是重要的前提,單條鏈接上的請求必須是單向的。從下圖可知,對於 RPC 場景,其單條鏈接的角色是固定的,只能是服務端鏈接或客戶端鏈接,且對一次請求的代理過程也是固定的,老是從服務端鏈接上收到一個請求,再從客戶端鏈接將請求轉發出去,所以 RPC 能夠直接使用上述平滑升級方案。
然而,在消息場景特別是 Msgbroker 場景下,以下圖所示,MOSN 上的鏈接請求其實是雙向的,不只客戶端會使用該鏈接進行消息的發送,服務端也會利用該鏈接將消息主動推送給 MOSN,這就會給上述鏈接遷移帶來新的問題和挑戰:
解決上述問題的思路其實很簡單,即爲在平滑升級的過程當中,禁止服務端向老 MOSN 發送投遞消息請求,保證即便在消息場景整個平滑升級過程當中的全部鏈接仍然是單工通訊的。具體對平滑升級流程的改動以下:
消息 Mesh 的流量調度以下圖所示。
首先,控制平面會將與流量調度相關的規則下發至 MOSN,規則主要包含該應用下全部容器節點的 IP 地址與流量權重,這是可以進行精細化流量調度的前提。
其次,當 MOSN 收到消息投遞請求時,會判斷請求的來源,若請求來源於其餘 MOSN 節點,則會直接將該請求轉發給客戶端,避免消息投遞請求的循環轉發,而若請求來源於消息服務端,則 MOSN 會根據自身的流量權重來決定下一步的路由,若自身的流量權重是100%,會一樣將該請求轉發給客戶端,但若自身權重小於100%,則會按照配置的權重將剩餘請求均勻轉發給其餘流量權重爲100%的 MOSN 節點。
最後,與 RPC 的點對點通訊方式不一樣,不管是消息發送端仍是訂閱端都只與消息服務端通訊,這意味着即便進行了消息 Mesh 化改造後,MOSN 也只與消息服務端通訊,同一個應用的 MOSN 節點之間是不存在消息鏈接的,爲了實現 MOSN 之間的消息流量轉發,則須要內置實現一個與業務應用進程同生命週期的消息轉發服務,由同應用內的全部其餘 MOSN 節點訂閱並在須要轉發時調用。
消息 Mesh 通過螞蟻消息中間件團隊大半年的打磨和沉澱,已經邁出了堅實的一大步:在開源社區遲遲未在消息 Mesh 上取得實質性進展時,咱們已經爲螞蟻內部主流消息中間件打通了數據平面。
同時也有充滿想象力的一小步:依賴消息的精細化流量調度,預期能夠發揮更大的業務價值,包括基於事件驅動的 Serverless 化應用多版本流量管理、流量着色、分組路由、細粒度的流量灰度與A/B策略等,等待着去開發與挖掘,
這些都在雙十一大促中取得了不俗的成績。將來,咱們將會持續加大對消息 Mesh的投入,爲消息 Mesh 支持更多的消息協議,賦予更多開箱即用的的消息流量管控和治理能力,並進一步結合 Knative 探索消息精細化流量調度在 Serverless 下的應用場景。最後,也歡迎志同道合的夥伴加入咱們,一塊兒參與金融級分佈式消息系統、雲原生時代的下一代消息系統的架構設計和研發。
公衆號:金融級分佈式架構(Antfin_SOFA)