網易音樂消息隊列實踐調研


業務背景

網易雲音樂從13年4月上線以來,業務和用戶突飛猛進。后台技術也從傳統的 Tomcat 集群到分布式微服務快速演進和迭代,在業務的不斷催生下,誕生了雲音樂的 RPC,API 網關和鏈路跟蹤等多種服務,消息隊列也從 RabbitMQ 集群遷移到 Kafka集群。對於消息隊列,更多處於使用階段,也在使用中出現很多問題。因此我們期望提供一種完全可控,出現問題我們自己能排查,能跟蹤,可以根據業務需求做定制改造的消息隊列。

生產環境

截止到2019年Q1,基於 RocketMQ 改造實現的消息隊列在網易雲音樂生產環境已經有6個集群。涉及順序消息,普通消息,多種高可用高可靠要求。

接入應用 數量 200+,每條業務線核心業務都有涉及。峰值 QPS 已達 30w+,topic 800+。在測試環境單個集群,由於環境很多,Topic 數量也瘋長,單個達到 4000+,未來隨着 kafka 遷移的更多,Topic 數量還會不斷上漲。

從 2018 年 11 月開始,禁止新業務接入kafka,新接入全部使用 RocketMQ,自2019 Q1推動Kafka業務遷移到RocketMQ,目前已經遷移70%+,業務整體穩定性得到極大提升。
隨着業務接入 RocketMQ 的增多,也不斷催生下游大數據生態的接入和使用。雲音樂大數據主要使用 flink,目前 flink 在運行 job 60+,其中 RocketMQ 消息量 每天達 8 億 +,這一塊未來還有不少增長空間。

技術選型

RocketMQ vs RabbitMQ vs Kafka性能對比

 

由於RabbitMQ持久化性能只有2.6萬/秒,不能滿足業務對高性能、高吞吐的要求。所以2017年從RabbitMQ遷移到Kafka

功能特性完備性對比 

RocketMQ系統架構

開源RocketMQ主要問題如下:

  • Broker僅提供了Master到Slave的復制功能,沒有Failover切換的能力
  • 事物消息不開源(我們開始研發時不開源)
  • 消息發送消費無追蹤(我們開始研發時不開源)
  • 告警與監控體系沒有
  • 開源控制台不完善

業務要求

  • 具備自主failover切換能力
  • 監控dashboard大盤
  • 根據不同業務場景提供靈活適配的QOS能力。如商城消息不能丟失,交易事物消息支持,消息發送消費追蹤,失敗排查等能力
  • 提供發送耗時,消費耗時,消費延遲,消費失敗異常等提供監控和告警能力
  • 功能強大和較完善的管理控制台
  • 對Nodejs和Python支持,另外要提供http接入能力

優化架構設計

以開源RocketMQ為內核,完全繼承開源 RocketMQ 具備的特性,然后以此為基礎進行擴展

改進措施:

  • 通過新增對broker健康檢查,提供主從broker自主failover能力
  • 發送耗時,消費耗時,消費失敗異常采集上報,寫入ES,根據閥值配置監控項
  • 有broker宕機,提供服務降級組件
  • 系統異常時,客戶端會將消息發送本地或者發送到容災集群,降低系統宕機時對業務的影響。
  • 提供系統巡檢能力,關鍵關鍵狀態異常快速發送報警

各組件交互流程如下:

  • NameServer提供topic路由信息發現,配置中心能力。
  • Broker 提供 topic 消息存儲,索引,查詢。同時 Broker 自身提供 HA 需要的復制,角色修改,探活,狀態獲取等 API。同時 Broker 定時向所有 Nameserver 注冊。
  • Nginx 提供發現 NameServer 能力,由運維將 nameserver 列表填寫到 hotdoc 中。避免 NameServer 變更業務重新配置上線。
  • 降級組件提供消息發送失敗的處理,在消息發送失敗的情況下 client 會將消息發送到容災集群,由降級組件統一處理保證發送方業務的穩定性。
  • Failover 組件檢查 Broker 狀態,Broker 宕機根據 QOS 要求切主。
  • Console 提供資源管控,消息查詢,軌跡跟蹤,監控報表,監控告警配置,死信重投等能力。
  • 巡檢組件巡檢消息隊列自身集群所有組件健康與服務狀態,有異常提前通知運維和消息隊列相關人員。
  • 監控組件提供監控報表數據采集處理,消息隊列大盤數據采集處理。
  • 告警組件主要采集告警信息,根據控制台配置的告警閥值和人員信息通知相應業務方。
  • 消息隊列大盤提供消息隊列集群自身的監控狀態,主備復制狀態,QPS 等集群大盤報表展示。

新增高級特性

RocketMQ為成為Apache頂級項目前,github開源版本是沒有消息軌跡跟蹤和事務特性的。網易雲音樂對代碼進行了修改和擴展,用於支持一下一些特性:

  • 消息軌跡跟蹤
  • 事務消息
  • 多環境隔離
  • 消費線程池自定義
  • 消費限流與降級

消息軌跡

以上實現和開源RocketMQ-v4.4中提供的消息軌跡實現機制一樣。和開源不同的是,雲音樂消息隊列提供發送消費、事物消息回查軌跡,同時消費失敗時,也在軌跡中提供失敗異常信息,這樣就能夠追蹤失敗原因。

事務消息

雲音樂通過修改存儲引擎實現自己的事物消息。提供事務消息回查按時間收斂能力,回查不到狀態超過次數進入死信,同時提供死信告警,事務消息回查死信處理能力。

多環境隔離 

雲音樂有很多條業務線,每條業務線都有很多個需求在做,同時各個業務線之間的訪問都是通過服務化的方式進行。為提升開發和測試效率,通過對 RPC 流量打標,的方式將流量隔離到相應環境,並一路透傳下去。消息也一樣,同一個需求發送的消息需要相應的環境開發,測試,和其他互不影響。因此雲音樂設計實現了消息隊列的隔離,加快業務開發測試,預發快速驗證能力。

消費線程池自定義支持 

開源 RocketMQ 消費端僅有一個消費線程池,多個topic的消費會互相影響。另外同一個消費端僅有一個 listener,如果是多個 topic,需要上層業務分發。雲音樂同一個應用都會有多個topic消費,有的多達 30+ 個。因此優先級高的 topic 需要自定義自己的消費線程池,優先級低的使用公共的。另外 每個topic也要有自己的listener,這樣就不用上層分發。基於上述要求,我們增加訂閱可以同時指定listener和consumeThreadExecutor 的方式。 

消費限流與降級

開源RocketMQ並沒有提供消費限流能力,基於Sentinel的是pull模式,而不是 push 模式,不能很好滿足雲音樂的業務需求。雲音樂的消息消費不少都要寫數據庫或者訪問第三方,這些消費和在線業務都是同一個應用,消息隊列自身雖然具備削峰填谷的能力,但是消費端會最大化使用消費線程池,這會對在線業務也產生影響。為保證在線業務優先,需要限制消費的速度,減少瞬時高峰消息消費對在線業務的影響。這部分可以通過調整消費線程池和消費qps來調整。我們選擇了調整消費 qps 消費限流的方式,這樣能和監控數據對起來並提供控制台動態調整能力,消費線程池調整雖然我們也提供動態調整線程池能力但是並不是線性的,調整起來沒有參考,比較困難。消費限流做在了底層而不是讓應用層自己做,和上層的區別時,上層限流了會觸發消息消費一次並且失敗,底層不會失敗也不算消費一次,因為還沒投遞上層業務。

多機房網絡bug修復

雲音樂有部分業務部署在建德,需要消費杭州的數據。這部分消費的機器總是隔三差五報 timeout。經過排查,發現 client 新建的連接總是在關閉創建循環,非常不穩定,這部分排查 remoting 層的代碼發現 client 建立連接存在並發問題,會將建立好的鏈接關閉。定位待開源 client 的 remoting bug 后,我們進行了修復。另外后來幾天,曲庫的業務同學也報發送3s超時,經過仔細排查,發現異常日志和連接建立日志和網絡建立並發問題的日志一致,協同業務升級到最新修復的客戶端解決。業務升級上線后如上所示,發送非常平穩,不再超時。

回饋開源社區

作為開源的受益者,部分改動已經提交到Apache RocketMQ官方且被采納,如消費限流,消費線程池,網絡 bug 修復等。

未來規划與展望

  • 從核心歌單和曲庫業務都有QPS高吞吐的push業務在運行,后續推廣到日志領域。
  • 涉及到日志傳輸開源 RocketMQ 有部分性能問題,需要做優化,目前我們已經完成這部分優化,由於優先級的關系,還沒推廣到日志傳輸相關應用。我們期望雲音樂的消息隊列能夠拓展到日志方面,將消息隊列具備的完善監控告警等能力賦能到大數據,NDC 訂閱(數據庫更新訂閱服務)。同時增加路由能力減少多機房間跨機房訪問。
  • RocketMQ只有網易音樂使用,未來聯合杭研,將網易音樂RocketMQ貢獻的擴展版推廣到其他大產品線。

參考資料

網易雲音樂的消息隊列改造之路:https://www.infoq.cn/article/2_D683SzYss0PjMdKXg2

 

博客引用地址:https://www.cnblogs.com/lizherui/p/12659030.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM