一、概述
消息隊列中間件(MQ)是不同系統(tǒng)之間消息傳遞,異步通信的常見組件,RabbitMQ、Kafka和RocketMQ是目前業(yè)界常見的3種消息中間件,本文重點闡述了他們特性差異、架構設計和處理常見問題的方案。
二、特性比較
RabbitMQ適合于中小規(guī)模的使用場景,是目前業(yè)界使用最廣泛的一種MQ,其完全實現(xiàn)了AMQP的協(xié)議,實現(xiàn)了非常豐富的消息可靠性的保障機制,和其他MQ相比,其在可靠性方面是最強的,但也正是由于可靠性方面實現(xiàn)機制過于沉重,導致其吞吐量并不高,在生產環(huán)境經(jīng)常會出現(xiàn)消息積壓的問題。
Kafka適合于實時流處理的使用場景,在大數(shù)據(jù)處理領域經(jīng)常見到,可以用來處理海量的日志數(shù)據(jù)和IoT海量數(shù)據(jù)采集,由于其基于文件順序讀寫的存儲架構和基于zero-copy的IO處理策略,使得他的吞吐量非常之高,性能非常之好,能夠達到百萬級別的數(shù)據(jù)處理吞吐量,其可靠性保障主要是基于多副本這種策略,所以可靠性方面明顯不如RabbitMQ。
RabbitMQ | Kafka | RocketMQ | |
---|---|---|---|
使用場景 | 中小規(guī)模的使用場景 | 實時流處理、海量日志數(shù)據(jù)處理 | 性能均衡,優(yōu)勢在分布式事務場景 |
可靠性 | 高,AMPQ協(xié)議保障 | 低,基于多副本機制保障 | 中等,基于事務的保障 |
吞吐量 | 低,萬級別 | 高,基于順序讀寫的存儲架構,百萬級別 | 中等,十萬級別 |
時效性 | 毫秒級別 | 毫秒級別 | 毫秒級別 |
優(yōu)點 | 可靠性非常高 | 吞吐量非常大,性能非常好,集群高可用 | 性能和功能全面,擅長分布式事務方向 |
缺點 | 吞吐量比較低,消息積累會影響性能,基于erlang開發(fā)不好定制 | 數(shù)據(jù)可靠性保障較低,會存在數(shù)據(jù)丟失 | 客戶端只支持Java,官方文檔支持較少 |
三、常見問題處理策略
1.可靠性保障
- RabbitMQ
- 持久化機制。RabbitMQ通過消息持久化機制來確保消息的可靠傳遞。生產者可以選擇將消息標記為持久化,使得即使在消息隊列服務器故障后,消息也能被保存并傳遞給消費者。
- RabbitMQ生產者提供的可靠性機制包括發(fā)布確認(Publish Confirm)、事務機制(Transaction),生產者可以通過發(fā)布確認和事務機制獲取消息是否成功被RabbitMQ接收和處理的確認;RabbitMQ生產者提供的可靠性保障機制包括消息確認機制(ACK),消費者可以通過消息確認機制來保障消息的可靠消費。
void basicAck(long deliveryTag, boolean multiple)//確認消息
void basicNack(long deliveryTag, boolean multiple, boolean requeue)//拒絕消息
void basicRecover(boolean requeue)//重發(fā)消息
- Kafka
- 持久化。kafka的消息在發(fā)送前會被持久化存儲到磁盤上,即使在服務器重啟后也不會丟失。但也需要對kafka的持久化消息設置失效時間,保障存儲空間的充足。
- 多副本。Kafka采用多副本機制,將消息復制到多個Broker節(jié)點上,即使其中一個Broker節(jié)點故障,仍然可以從其他副本節(jié)點讀取和傳遞消息。
-
RocketMQ
和kafka類似。
總結:RabbitMQ相比Kafka和RocketMQ,他有跟豐富的可靠性保障機制,包括保障生產者消息的可靠發(fā)送、數(shù)據(jù)的持久化還有消費者的可靠消費。
2.流控措施
流控措施主要是為了解決消息積壓的問題,如果生產者生成消息速率過快,而消費者消費消息的速率過慢,則會在MQ中形成消息擠壓,如果不及時處理就會造成MQ服務不可用或者OOM等問題。
- RabbitMQ
- 調整消費者消息消費速率。主要是用來控制消費任務的條數(shù)。可以使用QoS(Quality of Service)機制設置每個消費者的預取計數(shù),限制每次從隊列中獲取的消息數(shù)量,以控制消費者的處理速度。
- 調整消費者消息消費流量。主要是用來控制消費消息的大小。通過設置basic.qos或basic.consume命令的參數(shù)來控制消費者的處理速度,避免消息過多導致積壓。
/**
* prefetchSize:服務器傳送最大內容量(以八位字節(jié)計算),如果沒有限制,則為0
* prefetchCount:服務器每次傳遞的最大消息數(shù),如果沒有限制,則為0;
* global:如果為true,則當前設置將會應用于整個Channel(頻道)
**/
void basicQos(int prefetchSize, int prefetchCount, boolean global)
- Kafka
- 調整分區(qū)數(shù)和副本數(shù)。kafka下游消費者的數(shù)量和其分區(qū)數(shù)是一致的,所以Kafka通過分區(qū)和副本機制來實現(xiàn)消息的并行處理和負載均衡。可以根據(jù)消息的負載情況和消費者的處理能力,通過增加分區(qū)數(shù)量、調整副本分配策略等方式來提高系統(tǒng)的處理能力。
- 調整消息失效策略。kafka提供了消息的保存策略和清理策略,可以根據(jù)時間和數(shù)據(jù)的使用情況來設置。
- RocketMQ
- 動態(tài)調整消費者數(shù)量。RabbitMQ可以根據(jù)系統(tǒng)的負載情況和消息隊列的堆積情況,動態(tài)調整消費者的并發(fā)消費線程數(shù),以適應消息的處理需求。
- 調整數(shù)據(jù)的拉取或推送的模式。RocketMQ還提供了消息拉取和推拉模式,消費者可以根據(jù)自身的處理能力主動拉取消息,避免消息積壓過多。
總結:流控措施的幾種方式主要包括:(1)擴大下游消費者的消費速率和流量;(2)增大消費者的數(shù)量,擴大消費能力;(3)調整MQ的副本或分區(qū)數(shù),發(fā)揮下游消費者的最大消費能力;(4)拉取或推送模式的權衡。
3.重復消費問題
重復性消費問題主要需要解決是冪等性問題,對于重復下發(fā)的消息也能保障唯一性消費。
- RabbitMQ
- 冪等性處理。在消費者端實現(xiàn)冪等性邏輯,即無論消息被消費多少次,最終的結果應該保持一致。這可以通過在消費端進行唯一標識的檢查或者記錄已經(jīng)處理過的消息來實現(xiàn)。沒下消費任務時都去查詢該任務是否已被消費,這種是重復下發(fā)后處理的方式。
- 消息確認機制。消費者在處理完消息后,發(fā)送確認消息(ACK)給RabbitMQ,告知消息已經(jīng)成功處理。RabbitMQ根據(jù)接收到的確認消息來判斷是否需要重新投遞消息給其他消費者,這種是主動通知消息下發(fā)的方式。
- Kafka
- 消息確認機制。消費者在處理完消息后,提交已消費的偏移量(Offset)給Kafka,Kafka會記錄已提交的偏移量,以便在消費者重新啟動時從正確的位置繼續(xù)消費。消費者可以定期提交偏移量,確保消息只被消費一次。
- RocketMQ
- 使用消息唯一標識符(Message ID)。在消息發(fā)送時,為每條消息附加一個唯一標識符。消費者在處理消息時,可以通過判斷消息唯一標識符來避免重復消費??梢詫⑾D記錄在數(shù)據(jù)庫或緩存中,用于去重檢查。
總結:在MQ中處理重復消費的問題主要的思路有:(1)通過給消息加唯一性標識來過濾已經(jīng)消費的消息,對于像RocketMQ這種存在Messeage ID的,處理起來就比較簡單,就只需要對Messeage ID去重即可,對于像RabbitMQ和kafka這種可以將消息狀態(tài)保存在數(shù)據(jù)庫或緩存中進行唯一性去重;(2)消息確認機制,就是對于消息的消費會主動上報的,每次消費完就會進行確認,在RabbitMQ中是會恢復ACK標識,在kafka中是會恢復offset標識。文章來源:http://www.zghlxwxcb.cn/news/detail-719952.html
4.消息順序性
- RabbitMQ
- 單個隊列。rabbitmq 保證了同一個隊列中的消息按照發(fā)布的順序進入和出隊。
- Kafka
- 有序分區(qū)。kafka 保證了同一個分區(qū)(topic + partition)中的消息按照發(fā)布的順序存儲和消費。
- RocketMQ
- 有序分區(qū)。rokcetmq 保證了同一個隊列(topic + queueId)中的消息按照發(fā)布的順序存儲和消費。
參考資料
- MQ黃金三劍客:RabbitMQ、RocketMQ和Kafka深入解密常見問題及功能對比指南?:https://juejin.cn/post/7254267283249840184?utm_source=gold_browser_extension
- 【RabbitMQ.Client筆記】Qos與消息應答:https://www.cnblogs.com/fanfan-90/p/13589626.html (說明了通過Qos做限流,通過手動ACK來進行消息確認)
- 《RabbitMQ系列》之RabbitMQ的優(yōu)先級隊列:https://zhuanlan.zhihu.com/p/582787804(實現(xiàn)了優(yōu)先級隊列)
本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布!文章來源地址http://www.zghlxwxcb.cn/news/detail-719952.html
到了這里,關于RabbitMQ、Kafka和RocketMQ比較的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!