架構(gòu)與輕量級通信實踐)
1. 項目緣起從“螞蟻”到“Ling/Ring”的技術(shù)演進最近在整理過往的技術(shù)文檔時翻到了這份關(guān)于“螞蟻 Ling / Ring 2.6”的技術(shù)報告。說實話這個名字對于圈外人可能有點陌生甚至有些神秘但對于經(jīng)歷過那個時期、參與過相關(guān)技術(shù)探索的同行來說它代表了一段非常具體且充滿挑戰(zhàn)的實踐歷程。它不是某個開源框架的官方版本也不是某個大廠的公開產(chǎn)品而更像是一個內(nèi)部代號一個特定技術(shù)棧在特定階段的“快照”。今天我想拋開那些宏大的敘事和包裝就這份報告本身聊聊它背后所代表的技術(shù)選型、架構(gòu)迭代以及我們在那個階段踩過的坑、獲得的經(jīng)驗?!拔浵仭边@個前綴很容易讓人聯(lián)想到分布式、高并發(fā)、微服務(wù)這些概念這確實是當(dāng)時我們技術(shù)演進的核心方向。而“Ling”或“Ring”我更傾向于將其理解為一種架構(gòu)模式的形象化稱呼——一種環(huán)狀的、去中心化的、或者強調(diào)輕量級Light與聯(lián)動Link的設(shè)計思想。2.6這個版本號則標(biāo)志著它在某個關(guān)鍵能力或性能指標(biāo)上的一次重要迭代。這份技術(shù)報告的價值不在于它宣布了一個多么革命性的產(chǎn)品而在于它詳細(xì)記錄了一個技術(shù)方案從1.0到2.6版本演進過程中的核心決策、性能數(shù)據(jù)對比以及穩(wěn)定性治理的完整思考鏈路。對于正在設(shè)計或重構(gòu)自身中間件、通信框架、服務(wù)治理體系的團隊來說這里面有很多細(xì)節(jié)值得參考。2. 核心架構(gòu)解析“環(huán)”狀設(shè)計與輕量級通信要理解“Ling/Ring 2.6”首先得拆解它的核心架構(gòu)思想。報告中沒有明確定義“Ling”和“Ring”的具體區(qū)別但從上下文和實現(xiàn)細(xì)節(jié)來看我更愿意將其視為同一架構(gòu)理念下的兩種側(cè)重。2.1 “Ring”架構(gòu)去中心化的服務(wù)協(xié)作網(wǎng)絡(luò)“Ring”架構(gòu)的核心是構(gòu)建一個邏輯上的環(huán)形服務(wù)通信網(wǎng)絡(luò)。這里的“環(huán)”不是物理拓?fù)涠且环N邏輯關(guān)系和組織形式。在傳統(tǒng)的中心化服務(wù)發(fā)現(xiàn)如基于ZooKeeper、Eureka模型中所有服務(wù)節(jié)點都需要向一個或一組中心節(jié)點注冊和心跳中心節(jié)點成為單點故障和性能瓶頸的潛在風(fēng)險點。“Ring”架構(gòu)試圖解決這個問題。其基本思路是每個服務(wù)實例在啟動時除了完成自身的初始化還會獲取到一個當(dāng)前服務(wù)集群的視圖View。這個視圖不是從中心節(jié)點拉取的而是通過一種Gossip協(xié)議或類Gossip的輕量級廣播在服務(wù)實例間傳播和同步。最終每個實例都維護著一個包含部分或全部對等節(jié)點信息的列表這些節(jié)點在邏輯上形成一個“環(huán)”。當(dāng)服務(wù)A需要調(diào)用服務(wù)B時它不再詢問中心注冊中心而是根據(jù)自己的本地“環(huán)”視圖通過一致性哈希等算法直接定位到服務(wù)B的某個實例進行通信。這種設(shè)計帶來的直接好處是高可用性沒有絕對的中心節(jié)點任何一個實例的宕機都不會影響整個服務(wù)發(fā)現(xiàn)機制集群依然可以工作??蓴U展性新節(jié)點加入時通過協(xié)議將自身信息傳播到“環(huán)”內(nèi)其他節(jié)點更新本地視圖即可對中心節(jié)點無壓力。低延遲服務(wù)間調(diào)用免去了查詢注冊中心的網(wǎng)絡(luò)跳轉(zhuǎn)理論上通信路徑更短。但挑戰(zhàn)也同樣明顯視圖一致性如何保證所有節(jié)點看到的“環(huán)”視圖是最終一致的在網(wǎng)絡(luò)分區(qū)發(fā)生時如何防止出現(xiàn)“腦裂”這需要精妙的協(xié)議設(shè)計和參數(shù)調(diào)優(yōu)??蛻舳素?fù)擔(dān)服務(wù)發(fā)現(xiàn)的邏輯從中心轉(zhuǎn)移到了每個客戶端客戶端SDK需要集成更復(fù)雜的邏輯如視圖維護、故障檢測、負(fù)載均衡等。運維復(fù)雜度全局狀態(tài)的監(jiān)控和調(diào)試變得困難因為你無法在一個中心點看到全貌。在2.6版本的報告中重點優(yōu)化了視圖同步的效率和收斂速度引入了一種“增量式反熵”同步算法大幅減少了在節(jié)點頻繁上下線時集群內(nèi)部用于同步的冗余網(wǎng)絡(luò)流量。2.2 “Ling”特性極致的輕量級與靈活性如果說“Ring”定義了組織形態(tài)那么“Ling”則更側(cè)重于個體間的交互方式——輕量級Lightweight和靈巧聯(lián)動Linking。通信協(xié)議輕量化在2.6版本中默認(rèn)的RPC通信協(xié)議進行了大幅精簡。去掉了許多為了通用性而存在的復(fù)雜消息頭采用了更緊湊的二進制編碼如基于Protobuf的簡化封裝。一個典型的心跳包從原來的上百字節(jié)壓縮到了幾十字節(jié)。這對于大規(guī)模、高頻率的內(nèi)部服務(wù)間通信來說網(wǎng)絡(luò)帶寬的節(jié)省是立竿見影的。報告中的壓測數(shù)據(jù)顯示在同等QPS下2.6版本相比前序版本網(wǎng)絡(luò)IO降低了約15%。依賴與啟動輕量化早期的服務(wù)框架動輒需要引入數(shù)十MB的依賴包啟動一個空服務(wù)可能都需要幾百MB內(nèi)存和數(shù)秒時間?!癓ing”的目標(biāo)之一就是做減法。2.6版本通過模塊化重構(gòu)將核心通信、服務(wù)發(fā)現(xiàn)、配置管理等能力拆分為獨立的、可插拔的模塊。業(yè)務(wù)服務(wù)可以根據(jù)需要只引入必要的模塊。例如一個純消費服務(wù)可以不引入服務(wù)注冊和配置管理客戶端進一步減少資源占用。我們的一個邊緣計算場景應(yīng)用通過這種定制化引入內(nèi)存占用下降了40%啟動時間縮短了60%。動態(tài)聯(lián)動Linking這是“Ling”理念中比較精妙的一點。它不僅僅指服務(wù)間的調(diào)用更包括配置、特征、路由規(guī)則等的動態(tài)關(guān)聯(lián)與生效。2.6版本強化了“配置熱更新”與“服務(wù)路由”的聯(lián)動能力。例如當(dāng)某個服務(wù)的超時配置通過管理端修改后這個變更不僅能動態(tài)推送到所有服務(wù)實例還能與客戶端的負(fù)載均衡策略、熔斷器狀態(tài)進行聯(lián)動重置避免配置更新后客戶端因持有舊的失敗狀態(tài)而持續(xù)誤判。這種聯(lián)動不是硬編碼的而是通過內(nèi)部的事件總線Event Bus進行松耦合的通知各模塊訂閱自己關(guān)心的事件并作出反應(yīng)保證了系統(tǒng)的靈活性和可擴展性。3. 性能壓測與穩(wěn)定性治理數(shù)據(jù)背后的權(quán)衡技術(shù)報告中最硬核的部分永遠(yuǎn)是數(shù)據(jù)和對比。2.6版本報告用了大量篇幅展示性能壓測結(jié)果和穩(wěn)定性治理策略這里我挑幾個關(guān)鍵點展開。3.1 端到端延遲與吞吐量對比報告對比了2.5版本和2.6版本在相同硬件環(huán)境、相同業(yè)務(wù)壓力模型下的表現(xiàn)。P99延遲這是衡量服務(wù)響應(yīng)穩(wěn)定性的黃金指標(biāo)。在每秒5000次調(diào)用的壓力下2.6版本的P99延遲從2.5版本的45毫秒降低到了28毫秒優(yōu)化幅度接近40%。這個提升主要歸功于1新的二進制協(xié)議減少了序列化/反序列化開銷2客戶端本地路由策略優(yōu)化減少了無效的重試和路由選擇時間3網(wǎng)絡(luò)連接池的精細(xì)化管理避免了連接建立的延遲。吞吐量極限在逐步增大壓力的測試中2.6版本在達(dá)到系統(tǒng)資源CPU瓶頸前能支撐的QPS比2.5版本高出約25%。這得益于其更低的協(xié)程/線程切換開銷以及更高效的內(nèi)存分配器。報告指出在高壓下2.6版本的GC垃圾回收停頓時間明顯更短且更穩(wěn)定。這里有一個重要的實操心得壓測時一定要區(qū)分“內(nèi)網(wǎng)同機房”和“跨機房/跨地域”場景。2.6版本在低延遲網(wǎng)絡(luò)下的優(yōu)勢非常明顯但在模擬跨地域增加20ms網(wǎng)絡(luò)延遲的測試中其延遲優(yōu)化比例有所收窄吞吐量優(yōu)勢也變小了。這說明通信框架的優(yōu)化收益與網(wǎng)絡(luò)質(zhì)量強相關(guān)。如果你的服務(wù)部署環(huán)境網(wǎng)絡(luò)條件復(fù)雜那么框架在弱網(wǎng)下的自適應(yīng)能力如超時調(diào)整、退避策略比極限性能更重要。我們在預(yù)發(fā)環(huán)境壓測時就曾用TCTraffic Control工具模擬了不同的網(wǎng)絡(luò)丟包和延遲來驗證框架的健壯性。3.2 故障注入與混沌工程實踐報告沒有停留在“正常情況下的性能”而是專門用一章介紹了故障注入測試和相應(yīng)的穩(wěn)定性治理措施。典型故障場景及應(yīng)對節(jié)點瞬時故障隨機殺死某個服務(wù)實例的進程。2.6版本的“Ring”視圖能在平均1.5秒內(nèi)感知到節(jié)點下線并將流量從故障節(jié)點移除??蛻舳藭涗浭≌{(diào)用并短暫地將該節(jié)點標(biāo)記為“不健康”避免后續(xù)請求繼續(xù)發(fā)往死節(jié)點。這里的關(guān)鍵參數(shù)是“心跳超時時間”和“故障剔除窗口”需要根據(jù)實際網(wǎng)絡(luò)狀況調(diào)整設(shè)置過短會導(dǎo)致誤殺過長則影響故障恢復(fù)時間。網(wǎng)絡(luò)分區(qū)模擬機房網(wǎng)絡(luò)斷開。這是對“去中心化”架構(gòu)的最大考驗。2.6版本采用了一種“版本號邏輯時間戳”的機制來識別視圖的新舊。在網(wǎng)絡(luò)分區(qū)恢復(fù)后節(jié)點會對比視圖信息以版本更高的視圖為準(zhǔn)進行合并并觸發(fā)一次全量同步來確保一致性。這個過程可能會導(dǎo)致短時間內(nèi)部分請求失敗或路由混亂因此框架提供了“分區(qū)保護模式”開關(guān)開啟后在檢測到網(wǎng)絡(luò)異常時客戶端可以降級到使用本地緩存的路由信息或預(yù)配置的靜態(tài)路由犧牲一定的準(zhǔn)確性來保證可用性。依賴服務(wù)性能劣化模擬某個下游服務(wù)響應(yīng)變慢。2.6版本強化了熔斷器和限流器的聯(lián)動。當(dāng)某個實例的失敗率或慢調(diào)用比例超過閾值熔斷器會快速將其隔離。同時限流器會基于整個服務(wù)集群的健康狀況動態(tài)調(diào)整對該服務(wù)的總并發(fā)請求數(shù)防止線程池被慢調(diào)用拖垮。報告里詳細(xì)記錄了各種閾值如失敗率閾值、慢調(diào)用比例、半開狀態(tài)流量比例的調(diào)優(yōu)過程這些值沒有銀彈必須結(jié)合業(yè)務(wù)容忍度和實際流量形態(tài)來確定。注意混沌工程不是一次性的測試而應(yīng)該成為常態(tài)。我們當(dāng)時的實踐是在非核心業(yè)務(wù)線的低峰期定期自動執(zhí)行一組故障注入實驗并觀察監(jiān)控大盤和業(yè)務(wù)指標(biāo)是否出現(xiàn)異常。這套流程幫助我們提前發(fā)現(xiàn)了多個框架在極端場景下的邊界條件問題。4. 部署與運維從理論到實踐的挑戰(zhàn)一個框架設(shè)計得再精妙如果部署和運維成本高昂也很難落地。2.6版本報告在運維性方面做了不少改進但也帶來了新的挑戰(zhàn)。4.1 多環(huán)境與多集群部署“螞蟻”體系通常意味著龐大的業(yè)務(wù)集群。2.6版本支持通過“邏輯集群”和“環(huán)境標(biāo)簽”來對服務(wù)進行細(xì)粒度劃分。例如所有交易相關(guān)服務(wù)可以屬于“trade-cluster”并通過標(biāo)簽envprod、envpre來區(qū)分生產(chǎn)環(huán)境和預(yù)發(fā)環(huán)境。部署時最大的挑戰(zhàn)是版本灰度升級。由于“Ring”架構(gòu)是去中心化的你無法像操作中心注冊表那樣一鍵摘除所有老版本節(jié)點。2.6版本采用的方案是“雙注冊流量漸變”新版本實例啟動后會同時向老版本的“環(huán)”和新版本的“環(huán)”進行注冊通過不同的集群標(biāo)識或元數(shù)據(jù)。網(wǎng)關(guān)或上游服務(wù)通過配置路由規(guī)則逐步將流量權(quán)重從老版本“環(huán)”切換到新版本“環(huán)”比如從1%開始觀察監(jiān)控?zé)o異常后再逐步放大。待老版本流量完全切零且穩(wěn)定后再下線老版本實例。這個過程需要運維平臺提供強大的流量調(diào)度和監(jiān)控能力支持。我們當(dāng)時自研了一個簡單的控制臺用于管理這些集群標(biāo)簽和灰度策略雖然簡陋但解決了從0到1的問題。4.2 監(jiān)控與可觀測性體系構(gòu)建去中心化架構(gòu)讓傳統(tǒng)的基于中心節(jié)點的監(jiān)控方式失效了。2.6版本倡導(dǎo)的是“端到端”和“分布式追蹤”的可觀測性。Metrics指標(biāo)每個服務(wù)實例都會暴露大量的內(nèi)部指標(biāo)如請求QPS、延遲分布、錯誤碼統(tǒng)計、本地視圖節(jié)點數(shù)、網(wǎng)絡(luò)連接數(shù)等。這些指標(biāo)通過Prometheus的拉取模式或框架內(nèi)置的推送代理匯聚到時序數(shù)據(jù)庫中。關(guān)鍵是要設(shè)計好指標(biāo)的維度標(biāo)簽例如service_name,instance_ip,cluster,env以便于進行多維度聚合和下鉆排查。Tracing追蹤框架內(nèi)置了分布式追蹤能力為每個跨服務(wù)請求生成一個唯一的Trace ID并在整個調(diào)用鏈中傳遞。2.6版本優(yōu)化了追蹤采樣的性能開銷支持動態(tài)采樣率調(diào)整。在問題排查時通過Trace ID可以快速還原一個請求流經(jīng)的所有服務(wù)節(jié)點、各環(huán)節(jié)耗時這對于定位跨多個服務(wù)的性能瓶頸或異常至關(guān)重要。Logging日志框架本身會生成結(jié)構(gòu)化的運行日志但更重要的是推動業(yè)務(wù)日志與Trace ID關(guān)聯(lián)。我們規(guī)范了日志格式要求在所有業(yè)務(wù)日志的開頭打印Trace ID這樣當(dāng)從監(jiān)控指標(biāo)或追蹤鏈路發(fā)現(xiàn)問題時能迅速定位到相關(guān)的業(yè)務(wù)日志形成排查閉環(huán)。踩坑實錄初期我們過于關(guān)注框架自身的指標(biāo)忽略了業(yè)務(wù)指標(biāo)與框架指標(biāo)的關(guān)聯(lián)。有一次線上出現(xiàn)慢調(diào)用框架指標(biāo)顯示網(wǎng)絡(luò)和GC都正常但業(yè)務(wù)成功率下降。最后花了很長時間才發(fā)現(xiàn)是某個下游數(shù)據(jù)庫的慢查詢導(dǎo)致業(yè)務(wù)線程阻塞進而觸發(fā)了框架的線程池滿告警。后來我們完善了監(jiān)控大盤將核心業(yè)務(wù)指標(biāo)如訂單創(chuàng)建成功率、支付成功率與框架的P99延遲、錯誤率等指標(biāo)放在同一個視圖里并設(shè)置了關(guān)聯(lián)告警問題定位效率大大提升。5. 總結(jié)與反思架構(gòu)演進的得與失回顧“螞蟻 Ling / Ring 2.6”整個技術(shù)方案它代表了我們在追求高性能、高可用服務(wù)架構(gòu)方向上一次深入的嘗試。其價值不僅在于那些性能提升的百分比數(shù)字更在于整個設(shè)計和演進過程中積累的方法論。“得”主要體現(xiàn)在對極致性能的追求驗證了技術(shù)可能性通過協(xié)議精簡、去中心化設(shè)計確實在低延遲、高吞吐場景下達(dá)到了當(dāng)時非常領(lǐng)先的水平證明了自研技術(shù)路線的可行性。推動了團隊對分布式系統(tǒng)核心問題的理解在解決視圖一致性、故障恢復(fù)、網(wǎng)絡(luò)分區(qū)等問題的過程中團隊對CAP理論、共識算法、故障模式有了更深層次的、不再是紙上談兵的認(rèn)知。打造了一套完整的可觀測性實踐為了運維好這個去中心化系統(tǒng)我們被迫建立了從指標(biāo)、追蹤到日志的完整可觀測體系這套方法論后來被推廣到其他技術(shù)棧收益長遠(yuǎn)。“失”或說挑戰(zhàn)在于技術(shù)復(fù)雜度與人才成本這樣的自研框架學(xué)習(xí)曲線陡峭對開發(fā)人員的要求很高。新成員需要花費大量時間理解其架構(gòu)和配置增加了團隊的人力成本。生態(tài)與工具鏈的缺失相比Spring Cloud、Dubbo等成熟生態(tài)自研框架缺少豐富的第三方組件如各種配置中心、網(wǎng)關(guān)的官方適配、圖形化的運維工具和活躍的社區(qū)支持。很多工具都需要自己造維護負(fù)擔(dān)重。與行業(yè)標(biāo)準(zhǔn)漸行漸遠(yuǎn)當(dāng)云原生和Kubernetes成為事實標(biāo)準(zhǔn)Service Mesh服務(wù)網(wǎng)格理念興起后像Istio這樣的方案將服務(wù)治理能力下沉到基礎(chǔ)設(shè)施層用標(biāo)準(zhǔn)化的方式解決了多語言、流量管理等問題。我們當(dāng)時基于SDK的“強侵入式”架構(gòu)在擁抱云原生和Service Mesh時面臨著較大的遷移和改造成本。所以這份技術(shù)報告在今天看來更像是一個特定歷史時期、特定技術(shù)條件下的“深度優(yōu)化解”。它告訴我們在業(yè)務(wù)規(guī)模和性能要求達(dá)到一定臨界點時深入底層進行定制化改造是必要且有效的。但同時它也提醒我們技術(shù)選型需要有前瞻性要平衡好短期性能收益與長期維護成本、團隊發(fā)展以及技術(shù)潮流之間的關(guān)系。對于大多數(shù)業(yè)務(wù)場景采用成熟、有生態(tài)的社區(qū)方案或許才是性價比更高、更可持續(xù)的選擇。而對于那些真正有超大規(guī)模、超高性能需求的場景這份報告中關(guān)于去中心化設(shè)計、協(xié)議優(yōu)化、穩(wěn)定性治理的諸多細(xì)節(jié)依然閃爍著寶貴的光澤值得反復(fù)琢磨。