作者:vivo 互聯網中間件團隊- Liu Runyun
大量業務使用訊息中間件進行系統間的解耦、異步化、削峰填谷設計實作,公司內部前期基于RabbitMQ實作了一套高可用的訊息中間件平臺,隨著業務的持續增長,訊息體量隨之增大,對訊息中間件平臺提出了更高的要求,此外在運維程序中也遇到了高可用難以保障,功能特性不足等諸多問題,基于遇到的這些問題,決定引入RocketMQ進行替換,本文將介紹基于RocketMQ建設訊息中間件平臺并實作在線業務無感知的平滑遷移,
一、背景說明
vivo互聯網中間件團隊于2016年開始基于開源RabbitMQ向業務提供高可用訊息中間件平臺服務,
為解決好業務流量快速增長的問題,我們通過合理的業務集群拆分和動態調整,較好的交付了業務對訊息中間件平臺的平臺能力需求,
但是隨著業務長周期的迅猛發展,訊息體量也越來越大,在高并發、大流量場景下RabbitMQ的系統架構設計存在著一定的限制,主要有以下問題:
1.1 高可用能力不足
架構設計存在腦裂風險,并且默認腦裂后無法自動恢復,人工介入恢復存在資料丟失的風險,
為解決腦裂問題,可以選擇將網路例外后的處理調整為pause_minority模式,但是也帶來了可能微小的網路抖動也會導致集群故障無法恢復的問題,
1.2. 性能不足
業務訊息發送后通過exchange路由到對應的queue中,每一個queue由集群中的某個節點實際承載流量,高流量下集群中的某個節點可能會成為瓶頸,
queue由某個節點承載流量后無法快速遷移,強制遷移到其它低負載節點可能會導致queue不可用,這也導致了向集群中添加節點并無法快速提升集群的流量承載能力,
集群性能較低,經測驗使用三臺機器組成集群,可承載大概數萬tps左右,并且由于queue是由集群中某個節點實際承載的,也無法繼續提升某個queue的性能,這樣就無法支撐大流量業務,
訊息堆積到千萬或更多后會導致集群性能下降,甚至海量堆積后如果消費請求tps特別高,可能會因為磁盤的性能損耗導致發送性能下降,并且在訊息堆積太多時恢復時間長甚至無法恢復,
1.3 功能特性不足
RabbitMQ 默認情況下消費例外會執行立即重新投遞,少量的例外訊息也可能導致業務無法消費后續訊息,
功能特性上未支持事務訊息、順序訊息功能,
雖可自行實作訊息軌跡邏輯,但是會對集群產生非常大的性能損耗,在正式環境中實際無法基于RabbitMQ原生的能力實作訊息軌跡功能,
二、訊息中間件平臺的專案目標
基于以上問題,中間件團隊于2020年Q4開始進行了下一代訊息中間件平臺方案的調研,為保證下一代訊息中間件平臺符合業務新的需求,我們首先明確了訊息中間件平臺的建設目標,主要包含兩部分:
-
業務需求
-
平臺需求
2.1 業務需求分析
高性能:可支撐極高的tps,并且支持水平擴展,可快速滿足業務的流量增長需求,訊息中間件不應成為業務請求鏈路性能提升的瓶頸點,
高可用:極高的平臺可用性(>99.99%),極高的資料可靠性(>99.99999999%),
豐富的功能特性:支持集群、廣播消費;支持事務訊息、順序訊息、延時訊息、死信訊息;支持訊息軌跡,
2.2 平臺運維需求分析
-
可運維:業務使用權限校驗;業務生產消費流量限制;業務流量隔離與快速遷移能力,
-
可觀測:豐富的性能指標觀察集群的運行情況,
-
可掌握:可基于開源組件快速進行二次開發,豐富平臺功能特性和進行相關問題修復,
-
云原生:后續可基于容器化提供云原生訊息中間件,提供更高的彈性和可伸縮能力,
-
總結:需要建設高性能、高可靠的下一代訊息中間件,具備極高的資料可靠性,豐富的功能特性,并且需要完美兼容當前的RabbitMQ平臺,幫助業務快速遷移到新訊息中間件平臺,減少業務遷移成本,
三、開源組件選型調研
基于當前RabbitMQ平臺的問題和對下一代訊息中間件平臺的專案需求,我們開展了針對當前較流行的兩款訊息中間件:RocketMQ、Pulsar的調研,
調研程序中主要針對以下兩方面進行對比:
3.1 高可用能力分析對比
3.1.1 高可用架構與負載均衡能力對比

Pulsar部署架構(來源:Pulsar社區)

RocketMQ部署架構(來源:RocketMQ社區)
- Pulsar:
采用計算與存盤分離架構設計,可以實作海量資料存盤,并且支持冷熱資料分離存盤,
基于ZK和Manager節點控制Broker的故障切換以實作高可用,
Zookeeper采用分層分片存盤設計,天然支持負載均衡,
- RocketMQ:
采用存算一體架構設計,主從模式部署,master節點例外不影響訊息讀取,Topic采用分片設計,
需要二次開發支持主從切換實作高可用,
未實作Broker的自動負載均衡,可以將top n流量Topic分布到不同的Broker中實作簡單的負載均衡,
3.1.2 擴縮容與故障恢復對比
- Pulsar
Broker與BooKeeper獨立擴縮容,并且擴縮容后會完成自動負載均衡,
Broker節點無狀態,故障后承載Topic會自動轉移到其它Broker節點,完成故障秒級恢復,
BooKeeper由自動恢復服務進行ledger資料對齊,并恢復到設定的QW份,
故障期間已ack訊息不會丟失,未ack訊息需要客戶端重發,
- RocketMQ
Broker擴縮容后需要人工介入完成Topic流量均衡,可開發自動負載均衡組件結合Topic的讀寫權限控制自動化完成擴縮容后的負載均衡,
基于主從切換實作高可用,由于客戶端定期30秒從NameSrv更新路由,因此故障恢復時間在30~60秒,可以結合客戶端降級策略讓客戶端主動剔除例外Broker節點,實作更快故障恢復,
采用同步復制異步刷盤部署架構,在極端情況下會造成少量訊息丟失,采用同步復制同步刷盤,已寫入訊息不會丟失,
3.1.3 性能對比
- Pulsar
可支撐百萬Topic數量,實際受到ZK存盤元資料限制,
根據內部壓測1KB訊息可支撐TPS達數十萬,
- RocketMQ
邏輯上可支撐百萬Topic,實際在達到數萬時Broker與NameSrv傳輸心跳包可能超時,建議單集群不超過5萬,
根據壓測可支撐1KB訊息體TPS達10萬+,
3.2 功能特性對比

3.3 總結
從高可用架構分析,Pulsar基于Bookeeper組件實作了架構的計算與存盤分離,可以實作故障的快速恢復;RocketMQ采用了主從復制的架構,故障恢復依賴主從切換,
從功能特性分析,Pulsar支持了豐富的過期策略,支持了訊息去重,可以支持實時計算中訊息只消費一次的語意;RocketMQ在事務訊息、訊息軌跡、消費模式等特性對在線業務有更好的支持,
從這兩方面對比,最終選擇了RocketMQ構建我們下一代的訊息中間件平臺,
四、平滑遷移建設
通過技術調研,確定了基于RocketMQ建設下一代訊息中間件平臺,
為了實作業務從RabbitMQ平滑遷移到RocketMQ,就需要建設訊息網關實作訊息從AMQP協議轉換到RocketMQ;RabbitMQ與RocketMQ的元資料語意與存盤存在差異,需要實作元資料語意的映射與元資料的獨立存盤,
主要有以下四個事項需要完成:
4.1 訊息網關獨立部署與嵌入式部署差異對比

4.2 元資料定義映射與維護

4.3 互不干擾的高性能訊息推送
RabbitMQ采用推模式進行訊息消費,雖然RocketMQ也支持訊息推送消費,但是因為AMQP協議中通過prefetch引數限制了客戶端快取訊息數量以保證不會因快取太多訊息導致客戶端記憶體例外,因此在訊息網關實作訊息推送時也需要滿足AMQP協議的語意,
同時每個訊息網關都需要數千甚至數萬的queue的訊息推送,每個queue訊息消費速率存在差異,并且每個佇列可能隨時有訊息需要推送到客戶端進行消費,要保證不同queue之間的推送互不干擾且及時,
為了實作高效的、互不干擾的訊息推送,有以下策略:
每個queue采用獨立的執行緒,保證互不干擾和時效性,缺點是無法支撐海量queue的訊息推送,
基于信號量、阻塞佇列等,在感知到有可推送訊息和可消費服務端時按需進行訊息的推送,這樣可使用少量的執行緒即可完成高效的訊息推送,
最終選擇了第2種方案,資料流轉圖如下圖所示:

一個訊息消費程序:客戶端在啟動連接到訊息網關后,在訊息網關中會構建RocketMQ推送消費客戶端實體,并且注入自定義的ConsumeMessageService實體,同時使用一個信號量保存客戶端允許推送的訊息數量,
當訊息從集群側推送到訊息網關時,將訊息按照推送的批次封裝為一個任務保存在ConsumeMessageService實體的BlockingQueue中,同時推送執行緒會輪詢所有的ConsumeMessageService實體,如果發現本地快取有待消費的訊息并且有可消費訊息的業務客戶端,將任務提交到執行緒池中完成訊息的推送,
為了保證不會因為少量消費速率特別高的queue導致其它queue的訊息推送時效性降低,會限制每一個ConsumeMessageService只允許推送一定數量的訊息即轉到推送其它queue的訊息,以此即可保證所有queue的訊息推送的互不干擾和時效性,
在客戶端消費ack/uack后再次通過信號量通知下一次推送,這樣也保證了使用少量的執行緒資源即可完成海量訊息的推送需求,
4.4 消費啟停與消費限流能力實作
基于訊息網關,可以在訊息推送邏輯中增加消費啟停和消費限流邏輯,
消費啟停可以幫助業務快速實作消費的暫停或是部分例外節點停止訊息消費,
消費限流可以幫助業務控制訊息消費速率,避免對底層依賴產生太大壓力,
4.5 平臺架構

-
最終形成了以上的平臺架構,新建設了一個AMQP-proxy訊息網關服務實作AMQP訊息轉換到RocketMQ,支持業務的訊息生產消費,
-
建設了mq-meta服務維護集群的元資料資訊,
-
通過mq-controller控制集群的主從切換,實作集群的高可用,同時增加了集群監控,負載均衡模塊保障集群的高可用,
五、平臺建設進展與遷移收益
5.1 業務使用收益
5.1.1 更高、更穩定的訊息發送性能

原生RabbitMQ集群業務壓測性能

使用訊息網關后業務壓測性能
5.1.2 更豐富的功能特性
-
統一的訊息過期時間
-
消費例外訊息將按照梯度延時重投遞
-
直接支持廣播消費模式
-
全環境按需提供訊息軌跡功能
-
支持消費重置到以前的某個位點
5.1.3 業務使用特性變化
-
訊息將不再無限期保留,默認保留3~7天(實際保留時間根據集群配置決定)
-
消費例外將不再立即重投遞,將按照一定的梯度延時重投遞,多次例外后將變為死信訊息
-
直接支持廣播消費,注意廣播消費模式消費無例外重投遞,每個訊息每個節點只消費一次
-
業務生產消費性能可支持水平擴展
-
不支持消費優先級功能
-
默認消費超時時間15分鐘,消費超時后訊息重新投遞,消費超時時間可按需調整
-
支持消費啟停(全域或限制部分節點消費)
-
支持全域消費限流
-
限制訊息體大小,當前限制為256KB,超過將直接回傳失敗,后續將進行流量治理,限制發送大訊息體業務流量
5.2 平臺運維收益
業務從RabbitMQ遷移到RocketMQ后,可支撐業務流量從萬TPS級別提升到十萬TPS級別,可支撐業務容量從數億提升至百億級別,耗用機器資源下降50%以上,運維難度和成本均大大降低,同時可以基于訊息網關實作更加豐富的功能特性,
六、未來展望
未來,中間件團隊計劃在三個方面對訊息中間件進行迭代演進:
-
基于訊息網關能力豐富現有平臺功能特性,進行業務訊息治理,
-
過去五年中間件團隊基于開源RabbitMQ進行了RabbitMQ的高可用建設,發現直接讓業務方使用基于開源組件的SDK接入會帶來SDK升級困難,與后端訊息中間件型別系結的問題,未來我們計劃基于GPRC和訊息網關,實作訊息佇列引擎服務化,業務無需關心底層具體使用的開源訊息中間件選型,
-
調研RocketMQ5.0計算與存盤分離構架,進行訊息中間件架構的再升級,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/500852.html
標籤:其他
上一篇:設計模式之代理模式
下一篇:設計模式之建造者模式
