RocketMQ之消息中間件須要解決的問題

消息中間件須要解決哪些問題

1.Publish/Subscribe(發佈訂閱)

發佈訂閱是消息中間件最基本的功能前端

2.Message Priority(消息優先級)

在消息隊列中,每條消息都有不一樣的優先級,優先級高的先投遞。數據庫

因爲rocketmq的全部消息都是持久化的,按照優先級排序開銷會很是大,因此不支持持久化。可是能夠配置一個優先級高的隊列和一個普通的隊列,將不一樣的消息發送到不一樣的隊列。後端

優先級問題能夠分爲兩類:服務器

  1. 只要達到優先級目的便可,不須要嚴格劃分優先級。一般將優先級劃分爲高、中、低等幾個等級。每一個優先級用不一樣的topic表示。發送消息經過不一樣的topic來表示優先級。缺點是對業務的優先級作了妥協。
  2. 嚴格的優先級。若是讓MQ解決此問題,會對MQ的性能形成不少影響。這裏要確保一點,業務上是否確實需 要這種嚴格的優先級,若是將優先級壓縮成幾個,對業務的影響有多大?

3.Message Order(消息有序)

消息有序指的是一類消息消費時,能按照發送的順序來消費。例如:一個訂單產生了 3 條消息,分別是訂單創 建,訂單付款,訂單完成。消費時,要按照這個順序消費纔能有意義。可是同時訂單之間是能夠並行消費的。網絡

rocketmq嚴格保證消息有序性。異步

4.Message Filter(消息過濾)

  • Broker端消息過濾

    在broker中按照consumer的要求過濾,優勢是減小了對應consumer的無用消息的傳輸。但增長了broker的負擔,使得實現變複雜。分佈式

  • Consumer端消息過濾

    這種過濾方式可由應用徹底自定義實現,可是缺點是不少無用的消息要傳輸到 consumer端。性能

5.Message Persistence(消息持久化)

消息中間件一般採用幾種方式持久化:spa

  1. 持久化到數據庫
  2. 持久化到KV存儲
  3. 文件記錄形式的持久化,例如kafka、rocketmq
  4. 對內存數據作持久化鏡像

前三種持久化方式都具備將內存隊列 buffer 進行擴展的能力,後一種則當broker掛掉重啓後仍然能將以前內存的數據恢復出來。中間件

rocketmq參考了kafka的持久化方式,充分利用Linux文件系統內存cache來提升性能。

6.Message Reliablity(消息可靠性)

影響消息可靠性的幾種狀況:

  1. broker正常關閉
  2. broker異常crash
  3. OS crash
  4. 機器掉電,但能當即恢復供電狀況
  5. 機器不能開機(硬件損壞)
  6. 磁盤設備損壞

前面1-4四種狀況都屬於硬件資源可當即恢復的狀況。rocketmq在這四種狀況下能保證消息不丟,或丟失少許數據(依賴刷盤方式是同步仍是異步)。

5-6兩種狀況屬於單點故障,且不能恢復,一旦發生,在此單點上的消息所有丟失。rocketmq在這兩種狀況下,經過異步複製,可保證99%的消息不丟。經過同步雙寫技術能夠徹底避免單點,但會影響性能,適合對消息可靠性要求極高的場景,如與錢相關的應用。

7.Low Latency Messaging(低延遲)

在消息不堆積狀況下,消息到達 broker 後,能馬上到達 consumer。

rocketmq使用長輪詢 pulll 方式,可保證消息很是實時,消息實時性不低於 push。

8.At least Once(至少一次) 

指每一個消息必須投遞一次

rocketmq的consumer先pull消息到本地,消息完成後,才向服務器返回ask。若是沒有消費,必定不會ask消息。

9.Exactly Only Once(只有一次)

  • 發送消息階段不容許重複發送
  • 消費消息階段不容許重複消費

只有兩個條件都知足,才能認爲消息是去除的。而要實現以上兩點,在分佈式環境下,無疑會產生巨大開銷。

rocketmq並不保證此特性,而是要求在業務上去重,即消費消息作到冪等性。

10.Broker 的 Buffer

broker中的buffer一般指broker中一個隊列中的內存buffer大小。若是buffer滿了怎麼辦?

CORBA Notification 規範中處理方式:

  • RejectNewEvents:拒絕新來的消息,向producer返回錯誤碼
  • 按照特定策略丟棄已有消息

rockermq的隊列都是持久化磁盤,buffer大小是磁盤容量,且數據按期清理。

11.回溯消費

回溯消息指consumer成功消費的消息因爲業務上的需求,須要從新消費。要支持此功能,broker在向consumer投遞消息後,消息仍要保留。。而且從新消費通常是按照時間維度,例如因爲 Consumer 系統故障, 恢復後須要從新消費 1 小時前的數據,那麼 Broker 要提供一種機制,能夠按照時間維度來回退消費進度。

rocketmq支持按照時間回溯消息,時間維度精確到毫秒,能夠向前回溯,也能夠向後回溯。

12.消息堆積

消息中間件的主要功能是異步解耦,擋住前端的數據洪峯,保證後端系統的穩定性。這要求消息中間件具備必定的消息堆積能力。

消息堆積分兩種:

  • 一種是消息堆積在內存buffer中,一旦超過內存buffer,能夠根據丟棄策略來丟棄消息。這種消息堆積能力主要在於內存buffer的大小。且消息堆積後,性能降低不會太大。由於內存中數據多少對於對外提供的訪問能力影響有限。
  • 第二種是消息堆積在持久化存儲系統中,如:數據庫,KV存儲,文件記錄形式。當消息不能在內存cache中命中時,要不可避免的訪問磁盤,從而產生大量讀IO,讀IO的吞吐量直接決定了消息堆積後的訪問能力

13.分佈式事務

rocketmq採用第一階段發送Prepared消息時,拿到消息的offset,第二階段經過offset訪問消息,並修改狀態。offset就是數據的地址。

rocketmq實現事務方式,沒有經過KV存儲作,而是經過offset方式,存在一個顯著缺陷,即經過offset更改數據,會令系統的髒頁過多。

14.定時消息

定時消息指消息放到broker後,不能當即被consumer消費,需到特定時間點或等待特定時間後才能被消費。

若是支持任意時間精度,在broker層,就必須作消息排序,涉及到持久化,排序就會產生大量性能開銷。

rocketmq支持定時消息,但不支持任意精度,只支持特定level,如:5s,10s,1m等

15.消息重試

consumer消費消息失敗後,要提供一種重試機制,令消息再消費一次。

consumer消費消息失敗有幾種狀況:

  1. 因爲消息自己緣由,如反序列化失敗,消息數據自己無法處理(話費充值,當前手機號被註銷,不能充值)等。這種錯誤一般須要跳過這條消息,再消費其餘消息,這條失敗的消息即便馬上重試消費,基本不可能成功,因此最好提供一種定時重試機制。
  2. 因爲依賴的下游應用用服務不可用,如數據庫鏈接不可用,網絡緣由等。這種錯誤即便跳過當前失敗的消息,消費其餘消息一樣會報錯。

這種狀況建議應用sleep 30s,再消費下條消息,從而減輕broker重試消息的壓力。

相關文章
相關標籤/搜索