網易雲音樂中間件改造

網易雲音樂自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 在整個網易除雲音樂外並沒有其他大產品在使用,未來我們會聯合杭研,將消息隊列推廣到其他大產品線,將雲音樂對消息隊列的改進和特性普惠到其他大產品

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章