1. 程式人生 > >網易雲音樂的訊息佇列改造之路

網易雲音樂的訊息佇列改造之路

十年文案老司機,不如網易評論區。

網易雲音樂自2013年上線後,業務保持了高速增長。雲音樂除了提供好聽的音樂外,還留下了我們在樂和人上的美好回憶。本文整理自網易雲音樂訊息佇列負責人林德智在近期 Apache Flink&RocketMQ Meetup 上海站的分享,通過該文,您將瞭解到:

  • 網易雲音樂訊息佇列改造背景
  • 網易雲音樂業務對訊息佇列要求
  • 網易雲音樂訊息佇列架構設計
  • 網易雲音樂訊息佇列部分高階特性介紹
  • 網易雲音樂訊息佇列落地使用情況
  • 網易雲音樂訊息佇列未公開規劃

背景

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

調研結果

RabbitMQ 由於持久化場景下的吞吐量只有2.6萬,不能滿足我們業務吞吐量的需求,雲音樂在 2017 年將訊息佇列從 RabbitMQ 遷移到 Kafka 也是這個原因,因此不再考慮範圍之內。由於雲音樂整體業務的 QPS 較高,因此,ActiveMQ 也不在考慮範圍。

這裡主要對比 RocketMQ 與 Kafka:

Kafka 更偏向大資料,日誌處理,缺少死信,消費失敗自動重試,事物訊息,定時訊息,訊息過濾,廣播訊息等特性,另外 Kafka 沒有同步刷盤。雲音樂的業務更偏向於多 Topic,死信可溯源,消費失敗可收斂自動重試,高可用,自動 Failover 等特性。對於商城和社交業務來說,事物,順序 Topic 使用會比較多。Kafka 和RocketMQ 對比 :

http://jm.taobao.org/2016/03/24/rmq-vs-kafka

經過 RabbitMQ,Kafka 和 RocketMQ( ActiveMQ 效能較差,暫不考慮)的調研和分析後,我們發現 RocketMQ 比較適合雲音樂的通用業務,但是開源 RocketMQ 也有一些缺陷,只有我們解決了這些缺陷才能在業務中大規模使用。

開源 RocketMQ 的基本架構如下:(基本介紹參考)

開源 RocketMQ 主要問題有:

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

雲音樂業務對訊息佇列的要求

我們期望訊息佇列具備宕機 Failover 能力,根據不同業務場景提供不同 QOS 能力,如商城訊息不能丟失,交易事物訊息支援,訊息傳送消費追蹤,失敗排查等能力。

同時對業務比較關心的傳送耗時,消費耗時,消費延遲,消費失敗異常等提供監控和告警能力。同時對運維比較關心的整體執行水位和各項指標提供監控大盤,以及排查發現訊息佇列自身問題與長期運維能力。

另外雲音樂少部分業務是 Nodejs 和 Python 的,我們提供 HTTP 協議接入能力。

架構設計

整體架構如下:

以開源 RocketMQ 為核心,完全繼承開源 RocketMQ 具備的特性。為滿足高可用,我們增加了 failover 元件,對 broker 進行健康檢查提供快速切換能力。其中nginx 的 hotdoc 在開源 RocketMQ 裡面是個 jmenv,這一塊直接使用。

對於業務開發關心的監控,我們修改客戶端,把耗時,異常等資料採用系統訊息方式上報,由 Monitor 元件消費訊息並寫入 ES,並提供控制檯查詢能力。同時客戶端上報的資料,Alarm 也會消費一份,根據業務配置的監控項檢查告警,超出閥值直接發出告警。另外訊息系統也會出現宕機,宕機選主也有一段時間(秒級),雖然客戶端有重試能力,但是有些場景不能很好滿足。因此,訊息佇列提供了降級元件,在系統異常時,客戶端會將訊息傳送本地或者傳送到容災叢集,降低系統宕機時對業務的影響。

對於運維比較關心的系統巡檢,我們提供系統巡檢能力,將系統比較關鍵的狀態定時巡檢,異常則快速發出告警。對於運維比較關心的整體大盤,我們在 Monitor 元件中加入系統資料採集,將資料寫入 Influxdb,提供以 Grafana 為前端的 dashboard。另外我們也提供控制檯資源管控能力,將 Topic,ProducerGroup,ConsumerGroup,以及上下游應用關聯並管控起來。

各元件互動流程如下:

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

部分高階特性介紹

這部分是雲音樂根據自己業務的需求,對開源的修改和擴充。我們對開源 RocketMQ 的改動較多,由於篇幅的關係,這裡僅介紹這幾個特性,如 HTTP 協議實現和秒級延遲,高可用等這裡不做介紹,有興趣的同學可以交流。

訊息軌跡

這個特性和開源4.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 修復等。

訊息佇列在雲音樂的使用情況

截止目前為止,基於 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億+,這一塊未來還有不少增長空間。

未來規劃與展望

目前雲音樂訊息佇列的特性已經很多,並且能夠很好的滿足業務的需求。從核心歌單、曲庫業務到 QPS 很高的 push 業務,但在日誌方面還未涉及。

涉及到日誌傳輸開源 RocketMQ 有部分效能問題,需要做優化,目前我們已經完成這部分優化,由於優先順序的關係,還沒推廣到日誌傳輸相關應用。我們期望雲音樂的訊息佇列能夠拓展到日誌方面,將訊息佇列具備的完善監控告警等能力賦能到大資料,NDC 訂閱(資料庫更新訂閱服務)。同時增加路由能力減少多機房間跨機房訪問。

另外,訊息佇列 RocketMQ 在整個網易除雲音樂外並沒有其他大產品在使用,未來我們會聯合杭研,將訊息佇列推廣到其他大產品線,將雲音樂對訊息佇列的改進和特性普惠到其他大產品。

本文作者:林德智,網易雲音樂訊息佇列負責人,具有多年分散式訊息系統等中介軟體架構設計及研發經驗,對分散式系統有較深刻的理解。目前負責雲音樂訊息佇列及雲音樂部分穩定性效能相關工作。

 


本文作者:中介軟體小哥

原文連結

本文為雲棲社群原創內容,未經