基于消息队列 RocketMQ 的大型分布式应用上云最佳实践
作者|紹舒
審核&校對:歲月、佳佳
編輯&排版:雯燕
前言
消息隊列是分布式互聯(lián)網(wǎng)架構(gòu)的重要基礎(chǔ)設(shè)施,在以下場景都有著重要的應(yīng)用:
- 應(yīng)用解耦
- 削峰填谷
- 異步通知
- 分布式事務(wù)
- 大數(shù)據(jù)處理
并涉及互動直播、移動互聯(lián)網(wǎng)&物聯(lián)網(wǎng),IM 實時通信、Cache 同步、日志監(jiān)控等多個領(lǐng)域。
而本文主要圍繞著商業(yè)版本的消息隊列 RocketMQ,和開源版本 RocketMQ 進(jìn)行比較,并結(jié)合一些實踐中的場景來展示大型分布式應(yīng)用的上云最佳實踐。
核心能力
商業(yè)版本消息隊列 RocketMQ 相比較開源版本 RocketMQ 和其他競品,主要有以下幾點優(yōu)勢。
開箱即用、功能豐富
消息隊列 RocketMQ 提供了定時、事務(wù)、順序等多類型消息的支持,且支持廣播、集群兩種消費模式;另外在協(xié)議層面,提供 TCP/HTTP 多協(xié)議支持,還提供了 TAG/SQL 屬性過濾功能,極大程度地拓寬了用戶的使用場景。
高性能、無限拓展能力
消息隊列 RocketMQ 經(jīng)受了阿里核心電商歷年雙十一洪峰的考驗,支持千萬級 TPS 消息收發(fā)和億級消息堆積的能力,并且能夠為消息提供毫秒級端到端延遲保障,另外還提供分級存儲,支持海量消息的任意保存時間。
可觀測、免運維能力
消息隊列 RocketMQ 提供了一個可觀測性大盤,支持細(xì)粒度數(shù)據(jù)大盤,提供了消息全鏈路生命周期追蹤和查詢能力,對各個指標(biāo)提供了相應(yīng)的監(jiān)控報警功能;此外,還提供了消息回溯和死信隊列功能,能夠保證用戶的消息能夠隨時回溯消費。
高 SLA 和穩(wěn)定性保障
消息隊列 RocketMQ 的穩(wěn)定性是我們一貫、持續(xù)、穩(wěn)定投入的重要領(lǐng)域,提供了高可用部署和多副本寫入功能;另外也支持同城多 AZ 容災(zāi)和異地多活。
產(chǎn)品剖面
接下來,我們會從以上的產(chǎn)品核心能力中挑選幾個剖面,并且結(jié)合具體的場景和實踐來做進(jìn)一步的介紹。
多消息類型支持
高可用順序消息
商業(yè)版本消息隊列 RocketMQ 使用的順序消息我們稱之為高可用順序消息。在介紹高可用順序消息之前,首先簡要介紹下開源版本 RocketMQ 的順序消息。
順序消息分為兩種類型,全局順序消息和分區(qū)順序消息。
- 全局順序消息:在 RocketMQ 存儲層只會分配一個分區(qū),也就是說全局順序 Topic 的可用性跟單一副本的可用性強相關(guān),且不具備可擴展的能力。
- 分區(qū)順序消息:所有消息根據(jù) Sharding Key 進(jìn)行分區(qū)。同一個分區(qū)內(nèi)的消息按照嚴(yán)格的 FIFO 順序進(jìn)行發(fā)布和消費。Sharding Key 是順序消息中用來區(qū)分不同分區(qū)的關(guān)鍵字段。
下圖是分區(qū)順序消息的應(yīng)用場景,order ID 即為此時順序消息的 Sharding Key。
可以看到,無論是全局順序消息還是分區(qū)順序消息,都依賴了單一分區(qū)天然的 FIFO 特性來保證順序,因此順序性也只能在同一個分區(qū)內(nèi)保證,當(dāng)此分區(qū)所在的副本不可用時,順序消息并不具備重試到其他副本的能力,此時消息的順序性就難以得到保證。
為了解決這一問題,我們設(shè)計并實現(xiàn)了高可用順序消息。
高可用順序消息有以下幾個特點:
- 一個邏輯順序分區(qū)(PartitionGroup)下有多個物理分區(qū)。
- 其中任意一個物理分區(qū)是可寫的,那么整個邏輯分區(qū)是可寫且有序的。
- 我們基于 happened-before 的原則設(shè)計了一套基于分區(qū)位點的排序算法。
- 根據(jù)該算法,消費者在消費某一邏輯分區(qū)時,會從其所屬的各個物理分區(qū)中拉取消息并進(jìn)行合并排序,得出正確的消息順序流。
通過這樣的設(shè)計,高可用順序消息解決了下列幾點問題:
- 可用性問題:高可用順序消息將具備與普通消息一致的可用性,在某副本不可用時,可快速重試至其它副本。
- 可擴展性問題:普通順序消息,特別是普通全局順序消息,不具備良好的擴展能力,只能固定在特定的副本中。高可用順序消息的邏輯順序分區(qū)可以將物理順序分區(qū)分散在多個副本中。
- 熱點問題:普通順序消息根據(jù) Key 將一類消息 Hash 至同一個分區(qū)中,熱點 Key 會導(dǎo)致熱點分區(qū),高可用順序消息具備橫向擴展能力,可以為邏輯順序分區(qū)添加多個物理分區(qū)來消除熱點問題。
- 單點問題:普通全局順序消息,僅包含單分區(qū),極易出現(xiàn)單點故障,高可用順序消息可以消除全局順序消息的單點問題。
尤其需要注意的是熱點問題,在阿里巴巴內(nèi)部某電商業(yè)務(wù)大促時,因發(fā)送到順序 Topic 的某一特定的 ShardingKey 數(shù)量過多,集群中一個副本接收到了大量該 ShardingKey 的消息,導(dǎo)致該副本超出其負(fù)荷上限,造成了消息的延遲和堆積,一定程度上影響了業(yè)務(wù)。在使用了高可用順序消息之后,由于其在多物理分區(qū)中的負(fù)載均衡特性,提升了集群順序消息的承載能力,從而避免了熱點問題的出現(xiàn)。
秒級精準(zhǔn)定時消息
定時消息,是指客戶端當(dāng)前發(fā)送但希望在未來的某個時間內(nèi)收到的消息。定時消息廣泛應(yīng)用于各類調(diào)度系統(tǒng)或者業(yè)務(wù)系統(tǒng)之中。比如支付訂單,產(chǎn)生一個支付消息,系統(tǒng)通常需要在一定時間后處理該消息,判斷用戶是否支付成功,然后系統(tǒng)做相應(yīng)處理。
開源版本的 RocketMQ 只支持幾個指定的延遲級別,并不支持秒級精度的定時消息。而面向集團內(nèi)和云上多樣化的需求,開源版本的定時消息并不能滿足我們的需求,因此我們推出了秒級精準(zhǔn)定時消息。
如下圖所示,我們基于時間輪設(shè)計并實現(xiàn)了支持任意定時時間的秒級精準(zhǔn)定時消息,同時滿足以下特性:
- 任意定時時間
- 超長定時時間
- 海量定時消息
- 刪除定時消息
- 高可用
- 高性能
內(nèi)部某用戶有這樣的場景,期望在未來的某一分鐘的 30s 時刻處理這樣一個定時請求,開源版本的定時消息并不符合其需要,而秒級精準(zhǔn)定時消息在保證高可用、高性能的同時,滿足了其業(yè)務(wù)需求。
分布式事務(wù)消息
如下圖所示,在傳統(tǒng)的事務(wù)處理中,多個系統(tǒng)之間的交互耦合到一個事務(wù)中,造成整體的相應(yīng)時間長,回滾過程復(fù)雜,從而潛在影響了系統(tǒng)的可用性;而 RocketMQ 提供的分布式事務(wù)功能,在保證了系統(tǒng)松耦合和數(shù)據(jù)最終一致性的前提下,實現(xiàn)了分布式事務(wù)。
消息隊列 RocketMQ 提供的事務(wù)消息處理步驟如下:
- 發(fā)送方將半事務(wù)消息發(fā)送至消息隊列 RocketMQ 版服務(wù)端。
- 消息隊列 RocketMQ 版服務(wù)端將消息持久化成功之后,向發(fā)送方返回 Ack 確認(rèn)消息已經(jīng)發(fā)送成功,此時消息為半事務(wù)消息。
- 發(fā)送方開始執(zhí)行本地事務(wù)邏輯。
- 發(fā)送方根據(jù)本地事務(wù)執(zhí)行結(jié)果向服務(wù)端提交二次確認(rèn)(Commit 或是 Rollback),服務(wù)端收到 Commit 狀態(tài)則將半事務(wù)消息標(biāo)記為可投遞,訂閱方最終將收到該消息;服務(wù)端收到 Rollback 狀態(tài)則刪除半事務(wù)消息,訂閱方將不會接受該消息。
基于這樣的實現(xiàn),我們通過消息實現(xiàn)了分布式事務(wù)特性,即本地事務(wù)的執(zhí)行結(jié)果會最終反應(yīng)到訂閱方是否能接收到該條消息。
消息隊列 RocketMQ 的分布式事務(wù)消息廣泛地應(yīng)用于阿里巴巴核心交易鏈路中,通過分布式事務(wù)消息,實現(xiàn)了最小事務(wù)單元;交易系統(tǒng)和消息隊列之間,組成一個事務(wù)處理;下游系統(tǒng)(購物車、積分、其它)相互隔離,并行處理。
分級存儲
背景
隨著云上客戶的不斷增多,存儲逐漸成為 RocketMQ 運維的重要瓶頸,這包括并且不限于:
基于以上現(xiàn)狀,分級存儲方案應(yīng)運而生。
架構(gòu)
分級存儲的整體架構(gòu)如下:
通過這樣的設(shè)計,我們實現(xiàn)了消息數(shù)據(jù)的冷熱分離。
使用場景
基于分級存儲,我們進(jìn)一步拓展了用戶的使用場景:
穩(wěn)定性
消息隊列 RocketMQ 的穩(wěn)定性是我們一貫、持續(xù)、穩(wěn)定投入的重要領(lǐng)域。在介紹我們在穩(wěn)定性的最新工作之前,首先帶大家回顧下 RocketMQ 高可用架構(gòu)的演進(jìn)路線。
高可用架構(gòu)演進(jìn)路線
2012 年,RocketMQ 作為阿里巴巴全新一代的消息引擎問世,并隨后開源至社區(qū),第一代 RocketMQ 高可用架構(gòu)也隨之誕生。如下圖所示,第一代高可用架構(gòu)采取當(dāng)時流行的 Master-Slave 主從架構(gòu),寫流量經(jīng)過 Master 節(jié)點同步至 Slave 節(jié)點,讀流量也經(jīng)過 Master 節(jié)點并將消費記錄同步至 Slave 節(jié)點。當(dāng) Master 節(jié)點不可用時,整個副本組可讀不可寫。
2016 年,RocketMQ 云產(chǎn)品正式開始商業(yè)化,云時代單點故障頻發(fā),云產(chǎn)品需要完全面向失敗而設(shè)計,因此 RocketMQ 推出了第二代多副本架構(gòu),依托于 Zookeeper 的分布式鎖和通知機制,引入 Controller 組件負(fù)責(zé) Broker 狀態(tài)的監(jiān)控以及主備狀態(tài)機轉(zhuǎn)換,在主不可用時,備自動切換為主。第二代架構(gòu)是消息云產(chǎn)品規(guī)?;M(jìn)程中的核心高可用架構(gòu),為云產(chǎn)品規(guī)?;⑾铝撕柜R功勞。
2018 年,RocketMQ 社區(qū)對 Paxos 和 Raft 引入分布式協(xié)議有極大的熱情,RocketMQ 研發(fā)團隊在開源社區(qū)推出了基于 Raft 協(xié)議的 Dledger 存儲引擎,原生支持 Raft 多副本。
RocketMQ 高可用架構(gòu)已經(jīng)走過了三代,在集團、公有云和專有云多樣場景的實踐中,我們發(fā)現(xiàn)這三套高可用架構(gòu)都存在一些弊端:
- 第一代主備架構(gòu)只起到了冷備的作用,且主備切換需要人工介入,在大規(guī)模場景下有較大的資源浪費以及運維成本。
- 第二代架構(gòu)引入了 Zookeeper 和 Controller 節(jié)點,架構(gòu)上更加復(fù)雜,在主備切換做到了自動化,但故障轉(zhuǎn)移時間較長,一般是 10 秒左右完成選主。
- 第三代 Raft 架構(gòu)目前暫未在云上和阿里集團內(nèi)大規(guī)模應(yīng)用,且 Raft 協(xié)議就決定了需要選主,新主還需要被客戶端路由發(fā)現(xiàn),整個故障轉(zhuǎn)移時間依然較長;另外,強一致的 Raft 版本并未支持靈活的降級策略,無法在可用性和可靠性之間做靈活的權(quán)衡。
為了應(yīng)對云上日益增長的業(yè)務(wù)規(guī)模、更嚴(yán)苛的 SLA 要求、復(fù)雜多變的專有云部署環(huán)境,當(dāng)前的消息系統(tǒng)需要一種架構(gòu)簡單、運維簡單、有基于當(dāng)前架構(gòu)落地路徑的方案,我們將其稱作秒級 RTO 多副本架構(gòu)。
新一代秒級 RTO 多副本架構(gòu)
秒級 RTO 多副本架構(gòu)是消息中間件團隊設(shè)計實現(xiàn)的新一代高可用架構(gòu),包含副本組成機制、Failover 機制、對現(xiàn)有組件的侵入性修改等。
整個副本組有以下特點:
- Strong Leader/No Election:Leader 在部署時確定,整個生命周期內(nèi)不會發(fā)生切換,但可在故障時被替換。
- 僅 Leader 支持消息寫入:每一個副本組僅 Leader 接受消息寫入,Leader 不可用時,整個副本組不可寫入。
- 所有的副本支持消息讀取:雖然 Leader 上擁有全量的消息,Follower 上的消息量不對等,但所有的副本都支持消息的讀取。
- 靈活的副本組數(shù)量:可以基于可靠性、可用性和成本自由選擇副本組的數(shù)量。
- 靈活的 Quorum 數(shù)量:最終所有的消息都會同步到整個副本組上,但副本組內(nèi)可以靈活配置寫成功最小副本數(shù)。例如 2-3 模式,3 副本情況下,2 副本成功即為寫成功。同時,在副本不可用的情況下,Quorum 數(shù)量也可以動態(tài)自行降級。
在上述副本組的概念下,故障轉(zhuǎn)移可以復(fù)用當(dāng)前 RocketMQ 客戶端的機制來完成。如下圖所示:
- Producer 在主不可用時,靈活快速地切換至另一個副本組。
- Consumer 在某個副本不可用時可快速切換至同副本組另一個副本上進(jìn)行消息消費。
可觀測性
健康大盤
我們在可觀測性方面也做了大量的工作,為用戶提供了一個消息系統(tǒng)的可觀測性健康數(shù)據(jù)大盤。如下圖所示,用戶能夠清晰的看到實例級別、topic 級別、group 級別的各種監(jiān)控數(shù)據(jù),能夠全方面地監(jiān)控、診斷問題。
消息鏈路追蹤
另外我們還基于消息軌跡提供了消息全鏈路軌跡追蹤功能。如下圖所示,用戶能夠在控制臺上看到完整的消息生命周期、從消息的發(fā)送、存儲、到消費,整個鏈路都能被完整地記錄下來。
應(yīng)用場景
客戶痛點:業(yè)務(wù)出現(xiàn)消費堆積的用戶需要根據(jù)消息軌跡抽樣數(shù)據(jù),綜合分析后才能大致判斷引起問題原因,排查困難。
核心價值:提高線上運行問題排查的效率,和問題定位的準(zhǔn)確性。直接在健康大盤上快速發(fā)現(xiàn)風(fēng)險最高的 Topic 和 Group,并根據(jù)各個指標(biāo)的變化情況快速定位原因。例如消息處理時間過長可以擴容消費者機器或優(yōu)化消費業(yè)務(wù)邏輯,如果是失敗率過高可以快速查看日志排除錯誤原因。
事件驅(qū)動
大家一定非常熟悉 Gartner,在2018年的一個評估報告里,Gartner 將 Event-Driven Model,列為了未來10大戰(zhàn)略技術(shù)趨勢之一,并且,做出了兩個預(yù)測:
- 2022年,超過 60% 的新型數(shù)字化商業(yè)解決方案,都會采用事件通知的軟件模型。
- 2022年,超過 50% 的商業(yè)組織,將會參與到EDA生態(tài)系統(tǒng)當(dāng)中去。
同一年,CNCF 基金會也提出了 CloudEvents,意在規(guī)范不同云服務(wù)之間的事件通訊協(xié)議標(biāo)準(zhǔn)。到目前為止,CloudEvents也已經(jīng)發(fā)布了多個消息中間件的綁定規(guī)范。
可見事件驅(qū)動是未來業(yè)務(wù)系統(tǒng)的一個重要趨勢,而消息天然具備和事件的親近性,因此消息隊列 RocketMQ,是堅決擁抱事件驅(qū)動的。
談到消息和事件,這里做一個簡單的闡述:消息和事件是兩種不同形態(tài)的抽象,也意味著滿足不同的場景:
- 消息:消息是比事件更通用的抽象,常用于微服務(wù)調(diào)用之間的異步解耦,微服務(wù)調(diào)用之間往往需要等到服務(wù)能力不對等時才會去通過消息對服務(wù)調(diào)用進(jìn)行異步化改造;消息的內(nèi)容往往綁定了較強的業(yè)務(wù)屬性,消息的發(fā)送方對消息處理邏輯是有明確的預(yù)期的。
- 事件:事件相對于消息更加具像化,代表了事情的發(fā)送、條件和狀態(tài)的變化;事件源來自不同的組織和環(huán)境,所以事件總線天然需要跨組織;事件源對事件將被如何響應(yīng)沒有任何預(yù)期的,所以采用事件的應(yīng)用架構(gòu)是更徹底的解耦,采用事件的應(yīng)用架構(gòu)將更加具備可擴展性和靈活性。
在2020年,阿里云發(fā)布了事件總線 EventBridge?這一產(chǎn)品,其使命是作為云事件的樞紐,以標(biāo)準(zhǔn)化的 CloudEvents 1.0 協(xié)議連接云產(chǎn)品和云應(yīng)用,提供中心化的事件治理和驅(qū)動能力,幫助用戶輕松構(gòu)建松耦合、分布式的事件驅(qū)動架構(gòu);另外,在阿里云之外的云市場上有海量垂直領(lǐng)域的 SaaS 服務(wù),EventBridge 將以出色的跨產(chǎn)品、跨組織以及跨云的集成與被集成能力,助力客戶打造一個完整的、事件驅(qū)動的、高效可控的上云新界面。
而借助事件總線 EventBridge 提供的事件源功能,我們能夠打通消息到事件的鏈路,使得消息隊列 RocketMQ 具備事件驅(qū)動的動力,從而擁抱整個事件生態(tài)。接下來我們將借助一個案例,如下圖所示,為大家展示這一功能。
創(chuàng)建消息隊列 RocketMQ 主題
創(chuàng)建目標(biāo)服務(wù)
我們基于容器服務(wù)快速創(chuàng)建一個事件驅(qū)動的服務(wù),計算負(fù)載 Deployment 的 yaml 如下,該服務(wù)能夠響應(yīng)事件并將結(jié)果打印到標(biāo)準(zhǔn)輸出中。
前往容器服務(wù)控制臺,進(jìn)入服務(wù)與路由的服務(wù)頁面,創(chuàng)建一個私網(wǎng)訪問類型的 Service,并做好端口映射。
創(chuàng)建事件總線 EventBridge 自定義總線
我們來到事件總線 EventBridge 控制臺,創(chuàng)建一個自定義總線 demo-with-k8s。
創(chuàng)建事件總線 EventBridge 自定義總線規(guī)則
我們?yōu)榭偩€ demo-with-k8s 創(chuàng)建一個規(guī)則,并選擇 HTTP 作為事件目標(biāo),選擇專有網(wǎng)絡(luò)類型,選中對應(yīng)的 VPC、 VSwitch 以及安全組,并指定目標(biāo)URL,如下圖所示:
創(chuàng)建事件總線 EventBridge 事件源
我們?yōu)樵撟远x事件總線添加消息隊列 RocketMQ 版的自定義事件源。
發(fā)送 RocketMQ 消息
接下來我們回到消息隊列 RocketMQ 控制臺,通過控制臺的快速體驗消息生產(chǎn)功能發(fā)送一條內(nèi)容為 hello eventbridge 的消息到對應(yīng)的主題中去。
接下來我們就可以發(fā)現(xiàn),這條 RocketMQ 消息,以 CloudEvent 的形式被投遞到了對應(yīng)的服務(wù)中去,我們從而打通了消息到事件的鏈路。同時,基于我們上述提到的分級存儲功能,消息隊列 RocketMQ 轉(zhuǎn)變成了一個能夠源源不斷提供事件的數(shù)據(jù)倉庫,為整個事件生態(tài)提供了更加廣闊的場景。
事件驅(qū)動是未來商業(yè)組織和業(yè)務(wù)系統(tǒng)的重要趨勢,而消息隊列 RocketMQ 會堅定地?fù)肀н@一趨勢,將消息融入到事件的生態(tài)中。
總結(jié)
我們選取了消息隊列 RocketMQ 的幾個產(chǎn)品剖面,從多消息類型、分級存儲到穩(wěn)定性、可觀測性,再到面向未來的事件驅(qū)動,并結(jié)合與開源 RocketMQ 的對比,及具體應(yīng)用場景的分析,為大家展示了基于消息隊列 RocketMQ 的大型分布式應(yīng)用上云最佳實踐。
原文鏈接:https://developer.aliyun.com/article/799142?
版權(quán)聲明:本文內(nèi)容由阿里云實名注冊用戶自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,阿里云開發(fā)者社區(qū)不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。具體規(guī)則請查看《阿里云開發(fā)者社區(qū)用戶服務(wù)協(xié)議》和《阿里云開發(fā)者社區(qū)知識產(chǎn)權(quán)保護指引》。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,填寫侵權(quán)投訴表單進(jìn)行舉報,一經(jīng)查實,本社區(qū)將立刻刪除涉嫌侵權(quán)內(nèi)容。總結(jié)
以上是生活随笔為你收集整理的基于消息队列 RocketMQ 的大型分布式应用上云最佳实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【下载】《看见新力量》第二期,带你走进数
- 下一篇: 《Saas模式云原生数据仓库应用场景实践