【深度知識】分布式消息隊列(Active MQ/Rabbit MQ/Zero MQ/Kafka)差異化總結(jié)

1.摘要

本文將對Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ從17 個方面綜合對比作為消息隊列使用時的差異。

  • activiMq老牌消息中間件,api全面,但是吞吐量不大
  • rabbitMQ:吞吐量大,數(shù)據(jù)不易丟失
  • Kafaka吞吐量大,但是數(shù)據(jù)無法保證不丟失,主要面向大數(shù)據(jù)
  • rokectMQ:吞吐量大,保證數(shù)據(jù)不丟失,并且支持分布式事物,但是商業(yè)版需要收費

2.具體差異點

一、資料文檔

Kafka:資料數(shù)量中等。有Kafka作者自己寫的書,網(wǎng)上資料也有一些。

RabbitMQ:資料數(shù)量多。有一些不錯的書,網(wǎng)上資料多。

ZeroMQ:資料數(shù)量少。專門寫ZeroMQ的書較少,網(wǎng)上的資料多是一些代碼的實現(xiàn)和簡單介紹。

RocketMQ:資料數(shù)量少。專門寫RocketMQ的書目前有了兩本;網(wǎng)上的資料良莠不齊,官方文檔很簡潔,但是對技術(shù)細節(jié)沒有過多的描述。

ActiveMQ:資料數(shù)量多。沒有專門寫ActiveMQ的書,網(wǎng)上資料多。

二、開發(fā)語言

Kafka:Scala
RabbitMQ:Erlang
ZeroMQ:C
RocketMQ:Java
ActiveMQ:Java

三、支持的協(xié)議

Kafka:自己定義的一套…(基于TCP)
RabbitMQ:AMQP
ZeroMQ:TCP、UDP
RocketMQ:自己定義的一套…
ActiveMQ:OpenWire、STOMP、REST、XMPP、AMQP

四、消息存儲

1、Kafka
內(nèi)存、磁盤、數(shù)據(jù)庫。支持大量堆積。
Kafka的最小存儲單元是分區(qū),一個topic包含多個分區(qū),Kafka創(chuàng)建主題時,這些分區(qū)會被分配在多個服務器上,通常一個broker一臺服務器。
分區(qū)首領會均勻地分布在不同的服務器上,分區(qū)副本也會均勻的分布在不同的服務器上,確保負載均衡和高可用性,當新的broker加入集群的時候,部分副本會被移動到新的broker上。
根據(jù)配置文件中的目錄清單,Kafka會把新的分區(qū)分配給目錄清單里分區(qū)數(shù)最少的目錄。
默認情況下,分區(qū)器使用輪詢算法把消息均衡地分布在同一個主題的不同分區(qū)中,對于發(fā)送時指定了key的情況,會根據(jù)key的hashcode取模后的值存到對應的分區(qū)中。

2、RabbitMQ
內(nèi)存、磁盤。支持少量堆積。
RabbitMQ的消息分為持久化的消息和非持久化消息,不管是持久化的消息還是非持久化的消息都可以寫入到磁盤。
持久化的消息在到達隊列時就寫入到磁盤,并且如果可以,持久化的消息也會在內(nèi)存中保存一份備份,這樣可以提高一定的性能,當內(nèi)存吃緊的時候會從內(nèi)存中清除。
非持久化的消息一般只存在于內(nèi)存中,在內(nèi)存吃緊的時候會被換入到磁盤中,以節(jié)省內(nèi)存。
引入鏡像隊列機制,可將重要隊列“復制”到集群中的其他broker上,保證這些隊列的消息不會丟失。
配置鏡像的隊列,都包含一個主節(jié)點master和多個從節(jié)點slave,如果master失效,加入時間最長的slave會被提升為新的master,除發(fā)送消息外的所有動作都向master發(fā)送,然后由master將命令執(zhí)行結(jié)果廣播給各個slave,RabbitMQ會讓master均勻地分布在不同的服務器上,而同一個隊列的slave也會均勻地分布在不同的服務器上,保證負載均衡和高可用性。

3、ZeroMQ
消息發(fā)送端的內(nèi)存或者磁盤中。不支持持久化。

4、RocketMQ
磁盤。支持大量堆積。
commitLog文件存放實際的消息數(shù)據(jù),每個commitLog上限是1G,滿了之后會自動新建一個commitLog文件保存數(shù)據(jù)。
ConsumeQueue隊列只存放offset、size、tagcode,非常小,分布在多個broker上。
ConsumeQueue相當于CommitLog的索引文件,消費者消費時會從consumeQueue中查找消息在commitLog中的offset,再去commitLog中查找元數(shù)據(jù)。
ConsumeQueue存儲格式的特性,保證了寫過程的順序?qū)懕P(寫CommitLog文件),大量數(shù)據(jù)IO都在順序?qū)懲粋€commitLog,滿1G了再寫新的。
加上RocketMQ是累計4K才強制從PageCache中刷到磁盤(緩存),所以高并發(fā)寫性能突出。

5、ActiveMQ
內(nèi)存、磁盤、數(shù)據(jù)庫。支持少量堆積。

五、消息事務

Kafka:支持
RabbitMQ:支持。
客戶端將信道設置為事務模式,只有當消息被RabbitMQ接收,事務才能提交成功,否則在捕獲異常后進行回滾。使用事務會使得性能有所下降

ZeroMQ:不支持
RocketMQ:支持
ActiveMQ:支持

六、負載均衡

1、Kafka
支持負載均衡。

1)一個broker通常就是一臺服務器節(jié)點。
對于同一個Topic的不同分區(qū),Kafka會盡力將這些分區(qū)分布到不同的Broker服務器上,zookeeper保存了broker、主題和分區(qū)的元數(shù)據(jù)信息。
分區(qū)首領會處理來自客戶端的生產(chǎn)請求,Kafka分區(qū)首領會被分配到不同的broker服務器上,讓不同的broker服務器共同分擔任務。
每一個broker都緩存了元數(shù)據(jù)信息,客戶端可以從任意一個broker獲取元數(shù)據(jù)信息并緩存起來,根據(jù)元數(shù)據(jù)信息知道要往哪里發(fā)送請求。

2)Kafka的消費者組訂閱同一個topic,會盡可能地使得每一個消費者分配到相同數(shù)量的分區(qū),分攤負載。

3)當消費者加入或者退出消費者組的時候,還會觸發(fā)再均衡,為每一個消費者重新分配分區(qū),分攤負載。
Kafka的負載均衡大部分是自動完成的,分區(qū)的創(chuàng)建也是Kafka完成的,隱藏了很多細節(jié),避免了繁瑣的配置和人為疏忽造成的負載問題。

4)發(fā)送端由topic和key來決定消息發(fā)往哪個分區(qū),如果key為null,那么會使用輪詢算法將消息均衡地發(fā)送到同一個topic的不同分區(qū)中。如果key不為null,那么會根據(jù)key的hashcode取模計算出要發(fā)往的分區(qū)。

2、RabbitMQ
對負載均衡的支持不好。
1)消息被投遞到哪個隊列是由交換器和key決定的,交換器、路由鍵、隊列都需要手動創(chuàng)建。
RabbitMQ客戶端發(fā)送消息要和broker建立連接,需要事先知道broker上有哪些交換器,有哪些隊列。
通常要聲明要發(fā)送的目標隊列,如果沒有目標隊列,會在broker上創(chuàng)建一個隊列,如果有,就什么都不處理,接著往這個隊列發(fā)送消息。假設大部分繁重任務的隊列都創(chuàng)建在同一個broker上,那么這個broker的負載就會過大。
可以在上線前預先創(chuàng)建隊列,無需聲明要發(fā)送的隊列,但是發(fā)送時不會嘗試創(chuàng)建隊列,可能出現(xiàn)找不到隊列的問題,RabbitMQ的備份交換器會把找不到隊列的消息保存到一個專門的隊列中,以便以后查詢使用。
使用鏡像隊列機制建立RabbitMQ集群可以解決這個問題,形成master-slave的架構(gòu),master節(jié)點會均勻分布在不同的服務器上,讓每一臺服務器分攤負載。slave節(jié)點只是負責轉(zhuǎn)發(fā),在master失效時會選擇加入時間最長的slave成為master。
當新節(jié)點加入鏡像隊列的時候,隊列中的消息不會同步到新的slave中,除非調(diào)用同步命令,但是調(diào)用命令后,隊列會阻塞,不能在生產(chǎn)環(huán)境中調(diào)用同步命令。
2)當RabbitMQ隊列擁有多個消費者的時候,隊列收到的消息將以輪詢的分發(fā)方式發(fā)送給消費者。每條消息只會發(fā)送給訂閱列表里的一個消費者,不會重復。
這種方式非常適合擴展,而且是專門為并發(fā)程序設計的。
如果某些消費者的任務比較繁重,那么可以設置basicQos限制信道上消費者能保持的最大未確認消息的數(shù)量,在達到上限時,RabbitMQ不再向這個消費者發(fā)送任何消息。
3)對于RabbitMQ而言,客戶端與集群建立的TCP連接不是與集群中所有的節(jié)點建立連接,而是挑選其中一個節(jié)點建立連接。
但是RabbitMQ集群可以借助HAProxy、LVS技術(shù),或者在客戶端使用算法實現(xiàn)負載均衡,引入負載均衡之后,各個客戶端的連接可以分攤到集群的各個節(jié)點之中。

客戶端均衡算法:

輪詢法。按順序返回下一個服務器的連接地址。

加權(quán)輪詢法。給配置高、負載低的機器配置更高的權(quán)重,讓其處理更多的請求;而配置低、負載高的機器,給其分配較低的權(quán)重,降低其系統(tǒng)負載。

隨機法。隨機選取一個服務器的連接地址。
加權(quán)隨機法。按照概率隨機選取連接地址。
源地址哈希法。通過哈希函數(shù)計算得到的一個數(shù)值,用該數(shù)值對服務器列表的大小進行取模運算。
最小連接數(shù)法。動態(tài)選擇當前連接數(shù)最少的一臺服務器的連接地址。

3、ZeroMQ
去中心化,不支持負載均衡。本身只是一個多線程網(wǎng)絡庫。

4、RocketMQ
支持負載均衡。

一個broker通常是一個服務器節(jié)點,broker分為master和slave,master和slave存儲的數(shù)據(jù)一樣,slave從master同步數(shù)據(jù)。
1)nameserver與每個集群成員保持心跳,保存著Topic-Broker路由信息,同一個topic的隊列會分布在不同的服務器上。
2)發(fā)送消息通過輪詢隊列的方式發(fā)送,每個隊列接收平均的消息量。發(fā)送消息指定topic、tags、keys,無法指定投遞到哪個隊列(沒有意義,集群消費和廣播消費跟消息存放在哪個隊列沒有關系)。
tags選填,類似于 Gmail 為每封郵件設置的標簽,方便服務器過濾使用。目前只支 持每個消息設置一個 tag,所以也可以類比為 Notify 的 MessageType 概念。
keys選填,代表這條消息的業(yè)務關鍵詞,服務器會根據(jù) keys 創(chuàng)建哈希索引,設置后, 可以在 Console 系統(tǒng)根據(jù) Topic、Keys 來查詢消息,由于是哈希索引,請盡可能 保證 key 唯一,例如訂單號,商品 Id 等。

3)RocketMQ的負載均衡策略規(guī)定:
Consumer數(shù)量應該小于等于Queue數(shù)量,如果Consumer超過Queue數(shù)量,那么多余的Consumer 將不能消費消息。
這一點和Kafka是一致的,RocketMQ會盡可能地為每一個Consumer分配相同數(shù)量的隊列,分攤負載。

5、ActiveMQ
支持負載均衡。可以基于zookeeper實現(xiàn)負載均衡。

七、集群方式

1、Kafka
天然的‘Leader-Slave’無狀態(tài)集群,每臺服務器既是Master也是Slave。

分區(qū)首領均勻地分布在不同的Kafka服務器上,分區(qū)副本也均勻地分布在不同的Kafka服務器上,所以每一臺Kafka服務器既含有分區(qū)首領,同時又含有分區(qū)副本。

每一臺Kafka服務器是某一臺Kafka服務器的Slave,同時也是某一臺Kafka服務器的leader。
Kafka的集群依賴于zookeeper,zookeeper支持熱擴展,所有的broker、消費者、分區(qū)都可以動態(tài)加入移除,而無需關閉服務,與不依靠zookeeper集群的mq相比,這是最大的優(yōu)勢。

2、RabbitMQ
支持簡單集群,'復制'模式,對高級集群模式支持不好。
RabbitMQ的每一個節(jié)點,不管是單一節(jié)點系統(tǒng)或者是集群中的一部分,要么是內(nèi)存節(jié)點,要么是磁盤節(jié)點,集群中至少要有一個是磁盤節(jié)點。
在RabbitMQ集群中創(chuàng)建隊列,集群只會在單個節(jié)點創(chuàng)建隊列進程和完整的隊列信息(元數(shù)據(jù)、狀態(tài)、內(nèi)容),而不是在所有節(jié)點上創(chuàng)建。
引入鏡像隊列,可以避免單點故障,確保服務的可用性,但是需要人為地為某些重要的隊列配置鏡像。

3、ZeroMQ
去中心化,不支持集群。

4、RocketMQ
常用 多對'Master-Slave' 模式,開源版本需手動切換Slave變成Master。
Name Server是一個幾乎無狀態(tài)節(jié)點,可集群部署,節(jié)點之間無任何信息同步。
Broker部署相對復雜,Broker分為Master與Slave,一個Master可以對應多個Slave,但是一個Slave只能對應一個Master。
Master與Slave的對應關系通過指定相同的BrokerName,不同的BrokerId來定義,BrokerId為0表示Master,非0表示Slave。
Master也可以部署多個。每個Broker與Name Server集群中的所有節(jié)點建立長連接,定時注冊Topic信息到所有Name Server。
Producer與Name Server集群中的其中一個節(jié)點(隨機選擇)建立長連接,定期從Name Server取Topic路由信息,并向提供Topic服務的Master建立長連接,且定時向Master發(fā)送心跳。Producer完全無狀態(tài),可集群部署。
Consumer與Name Server集群中的其中一個節(jié)點(隨機選擇)建立長連接,定期從Name Server取Topic路由信息,并向提供Topic服務的Master、Slave建立長連接,且定時向Master、Slave發(fā)送心跳。
Consumer既可以從Master訂閱消息,也可以從Slave訂閱消息,訂閱規(guī)則由Broker配置決定。
客戶端先找到NameServer, 然后通過NameServer再找到 Broker。
一個topic有多個隊列,這些隊列會均勻地分布在不同的broker服務器上。RocketMQ隊列的概念和Kafka的分區(qū)概念是基本一致的,Kafka同一個topic的分區(qū)盡可能地分布在不同的broker上,分區(qū)副本也會分布在不同的broker上。
RocketMQ集群的slave會從master拉取數(shù)據(jù)備份,master分布在不同的broker上。

5、ActiveMQ
支持簡單集群模式,比如'主-備',對高級集群模式支持不好。

八、管理界面

Kafka:一般
RabbitMQ:好
ZeroMQ:無
RocketMQ:有管理后臺, 但不是項目里自帶, 需要自己啟動一個單獨的管理后臺實例
ActiveMQ:一般

九、可用性

Kafka:非常高(分布式)
RabbitMQ:高(主從)
ZeroMQ:高
RocketMQ:非常高(分布式)
ActiveMQ:高(主從)

十、消息重復

Kafka:支持at least once、at most once
RabbitMQ:支持at least once、at most once
ZeroMQ:只有重傳機制,但是沒有持久化,消息丟了重傳也沒有用。既不是at least once、也不是at most once、更不是exactly only once
RocketMQ:支持at least once
ActiveMQ:支持at least once

十一、吞吐量TPS
Kafka:極大
Kafka按批次發(fā)送消息和消費消息。發(fā)送端將多個小消息合并,批量發(fā)向Broker,消費端每次取出一個批次的消息批量處理。
RabbitMQ:比較大
ZeroMQ:極大
RocketMQ:大
RocketMQ接收端可以批量消費消息,可以配置每次消費的消息數(shù),但是發(fā)送端不是批量發(fā)送。
ActiveMQ:比較大

十二、訂閱形式和消息分發(fā)

1、Kafka
基于topic以及按照topic進行正則匹配的發(fā)布訂閱模式。
1)發(fā)送
發(fā)送端由topic和key來決定消息發(fā)往哪個分區(qū),如果key為null,那么會使用輪詢算法將消息均衡地發(fā)送到同一個topic的不同分區(qū)中。如果key不為null,那么會根據(jù)key的hashcode取模計算出要發(fā)往的分區(qū)。
2)接收
consumer向群組協(xié)調(diào)器broker發(fā)送心跳來維持他們和群組的從屬關系以及他們對分區(qū)的所有權(quán)關系,所有權(quán)關系一旦被分配就不會改變除非發(fā)生再均衡(比如有一個consumer加入或者離開consumer group),consumer只會從對應的分區(qū)讀取消息。

Kafka限制consumer個數(shù)要少于分區(qū)個數(shù),每個消息只會被同一個 Consumer Group的一個consumer消費(非廣播)。

Kafka的 Consumer Group訂閱同一個topic,會盡可能地使得每一個consumer分配到相同數(shù)量的分區(qū),不同 Consumer Group訂閱同一個主題相互獨立,同一個消息會被不同的 Consumer Group處理。

2、RabbitMQ
提供了4種:direct、topic、Headers和fanout。
1)發(fā)送
先要聲明一個隊列,這個隊列會被創(chuàng)建或者已經(jīng)被創(chuàng)建,隊列是基本存儲單元。
由exchange和key決定消息存儲在哪個隊列。

direct>發(fā)送到和bindingKey完全匹配的隊列。

topic>路由key是含有"."的字符串,會發(fā)送到含有“*”、“#”進行模糊匹配的bingKey對應的隊列。

fanout>與key無關,會發(fā)送到所有和exchange綁定的隊列

headers>與key無關,消息內(nèi)容的headers屬性(一個鍵值對)和綁定鍵值對完全匹配時,會發(fā)送到此隊列。此方式性能低一般不用

2)接收
RabbitMQ的隊列是基本存儲單元,不再被分區(qū)或者分片,對于我們已經(jīng)創(chuàng)建了的隊列,消費端要指定從哪一個隊列接收消息。
當RabbitMQ隊列擁有多個消費者的時候,隊列收到的消息將以輪詢的分發(fā)方式發(fā)送給消費者。每條消息只會發(fā)送給訂閱列表里的一個消費者,不會重復。
這種方式非常適合擴展,而且是專門為并發(fā)程序設計的。
如果某些消費者的任務比較繁重,那么可以設置basicQos限制信道上消費者能保持的最大未確認消息的數(shù)量,在達到上限時,RabbitMQ不再向這個消費者發(fā)送任何消息。

3、ZeroMQ
點對點(p2p)。

4、RocketMQ
基于topic/messageTag以及按照消息類型、屬性進行正則匹配的發(fā)布訂閱模式。
1)發(fā)送
發(fā)送消息通過輪詢隊列的方式發(fā)送,每個隊列接收平均的消息量。發(fā)送消息指定topic、tags、keys,無法指定投遞到哪個隊列(沒有意義,集群消費和廣播消費跟消息存放在哪個隊列沒有關系)。
tags選填,類似于 Gmail 為每封郵件設置的標簽,方便服務器過濾使用。目前只支 持每個消息設置一個 tag,所以也可以類比為 Notify 的 MessageType 概念。
keys選填,代表這條消息的業(yè)務關鍵詞,服務器會根據(jù) keys 創(chuàng)建哈希索引,設置后, 可以在 Console 系統(tǒng)根據(jù) Topic、Keys 來查詢消息,由于是哈希索引,請盡可能 保證 key 唯一,例如訂單號,商品 Id 等。

2)接收
廣播消費。一條消息被多個Consumer消費,即使Consumer屬于同一個ConsumerGroup,消息也會被ConsumerGroup中的每個Consumer都消費一次。
集群消費。一個 Consumer Group中的Consumer實例平均分攤消費消息。例如某個Topic有 9 條消息,其中一個Consumer Group有3個實例,那么每個實例只消費其中的 3 條消息。即每一個隊列都把消息輪流分發(fā)給每個consumer。

5、ActiveMQ
點對點(p2p)、廣播(發(fā)布-訂閱)
點對點模式,每個消息只有1個消費者;
發(fā)布/訂閱模式,每個消息可以有多個消費者。
1)發(fā)送
點對點模式:先要指定一個隊列,這個隊列會被創(chuàng)建或者已經(jīng)被創(chuàng)建。
發(fā)布/訂閱模式:先要指定一個topic,這個topic會被創(chuàng)建或者已經(jīng)被創(chuàng)建。
2)接收
點對點模式:對于已經(jīng)創(chuàng)建了的隊列,消費端要指定從哪一個隊列接收消息。
發(fā)布/訂閱模式:對于已經(jīng)創(chuàng)建了的topic,消費端要指定訂閱哪一個topic的消息。

十三、順序消息

Kafka:支持。
設置生產(chǎn)者的max.in.flight.requests.per.connection為1,可以保證消息是按照發(fā)送順序?qū)懭敕掌鞯模词拱l(fā)生了重試。
Kafka保證同一個分區(qū)里的消息是有序的,但是這種有序分兩種情況:

①key為null,消息逐個被寫入不同主機的分區(qū)中,但是對于每個分區(qū)依然是有序的
②key不為null , 消息被寫入到同一個分區(qū),這個分區(qū)的消息都是有序。
RabbitMQ:不支持
ZeroMQ:不支持
RocketMQ:支持
ActiveMQ:不支持

十四、消息確認

1、Kafka
支持。
1)發(fā)送方確認機制
ack=0,不管消息是否成功寫入分區(qū)
ack=1,消息成功寫入首領分區(qū)后,返回成功
ack=all,消息成功寫入所有分區(qū)后,返回成功。
2)接收方確認機制
自動或者手動提交分區(qū)偏移量,早期版本的Kafka偏移量是提交給Zookeeper的,這樣使得zookeeper的壓力比較大,更新版本的Kafka的偏移量是提交給Kafka服務器的,不再依賴于zookeeper群組,集群的性能更加穩(wěn)定。
2、RabbitMQ
支持。
1)發(fā)送方確認機制,消息被投遞到所有匹配的隊列后,返回成功。如果消息和隊列是可持久化的,那么在寫入磁盤后,返回成功。支持批量確認和異步確認。
2)接收方確認機制,設置autoAck為false,需要顯式確認,設置autoAck為true,自動確認。
當autoAck為false的時候,RabbitMQ隊列會分成兩部分,一部分是等待投遞給consumer的消息,一部分是已經(jīng)投遞但是沒收到確認的消息。
如果一直沒有收到確認信號,并且consumer已經(jīng)斷開連接,RabbitMQ會安排這個消息重新進入隊列,投遞給原來的消費者或者下一個消費者。
未確認的消息不會有過期時間,如果一直沒有確認,并且沒有斷開連接,RabbitMQ會一直等待,RabbitMQ允許一條消息處理的時間可以很久很久。

3、ZeroMQ
支持。

4、RocketMQ
支持。

5、ActiveMQ
支持。

十五、消息回溯

Kafka:支持指定分區(qū)offset位置的回溯
RabbitMQ:不支持
ZeroMQ:不支持
RocketMQ:支持指定時間點的回溯
ActiveMQ:不支持

十六、消息重試

1、Kafka
不支持,但是可以實現(xiàn)。
Kafka支持指定分區(qū)offset位置的回溯,可以實現(xiàn)消息重試。

2、RabbitMQ
不支持,但是可以利用消息確認機制實現(xiàn)。
RabbitMQ接收方確認機制,設置autoAck為false。

當autoAck為false的時候,RabbitMQ隊列會分成兩部分,一部分是等待投遞給consumer的消息,一部分是已經(jīng)投遞但是沒收到確認的消息。

如果一直沒有收到確認信號,并且consumer已經(jīng)斷開連接,RabbitMQ會安排這個消息重新進入隊列,投遞給原來的消費者或者下一個消費者。

3、ZeroMQ
不支持。

4、RocketMQ
支持。
消息消費失敗的大部分場景下,立即重試99%都會失敗,所以RocketMQ的策略是在消費失敗時定時重試,每次時間間隔相同。
1)發(fā)送端的 send 方法本身支持內(nèi)部重試,重試邏輯如下:
至多重試3次;
如果發(fā)送失敗,則輪轉(zhuǎn)到下一個broker;
這個方法的總耗時不超過sendMsgTimeout 設置的值,默認 10s,超過時間不在重試。
2)接收端。
Consumer 消費消息失敗后,要提供一種重試機制,令消息再消費一次。Consumer 消費消息失敗通常可以分為以下兩種情況:
由于消息本身的原因,例如反序列化失敗,消息數(shù)據(jù)本身無法處理(例如話費充值,當前消息的手機號被注銷,無法充值)等。定時重試機制,比如過 10s 秒后再重試。

由于依賴的下游應用服務不可用,例如 db 連接不可用,外系統(tǒng)網(wǎng)絡不可達等。即使跳過當前失敗的消息,消費其他消息同樣也會報錯。這種情況可以 sleep 30s,再消費下一條消息,減輕 Broker 重試消息的壓力。

5、ActiveMQ
不支持。

十七、并發(fā)度

1、Kafka
并發(fā)度高。
一個線程一個消費者,Kafka限制消費者的個數(shù)要小于等于分區(qū)數(shù),如果要提高并行度,可以在消費者中再開啟多線程,或者增加consumer實例數(shù)量。

2、RabbitMQ
并發(fā)度極高。本身是用Erlang語言寫的,并發(fā)性能高。
可在消費者中開啟多線程,最常用的做法是一個channel對應一個消費者,每一個線程把持一個channel,多個線程復用connection的tcp連接,減少性能開銷。
當RabbitMQ隊列擁有多個消費者的時候,隊列收到的消息將以輪詢的分發(fā)方式發(fā)送給消費者。每條消息只會發(fā)送給訂閱列表里的一個消費者,不會重復。
這種方式非常適合擴展,而且是專門為并發(fā)程序設計的。
如果某些消費者的任務比較繁重,那么可以設置basicQos限制信道上消費者能保持的最大未確認消息的數(shù)量,在達到上限時,RabbitMQ不再向這個消費者發(fā)送任何消息。

3、ZeroMQ
并發(fā)度高。
4、RocketMQ
并發(fā)度高。
1)RocketMQ限制消費者的個數(shù)少于等于隊列數(shù),但是可以在消費者中再開啟多線程,這一點和Kafka是一致的,提高并行度的方法相同。
修改消費并行度方法
同一個 ConsumerGroup 下,通過增加 Consumer 實例數(shù)量來提高并行度,超過訂閱隊列數(shù)的 Consumer實例無效。提高單個 Consumer 的消費并行線程,通過修改參數(shù)consumeThreadMin、consumeThreadMax
2)同一個網(wǎng)絡連接connection,客戶端多個線程可以同時發(fā)送請求,連接會被復用,減少性能開銷。

5、ActiveMQ
并發(fā)度高。
單個ActiveMQ的接收和消費消息的速度在1萬筆/秒(持久化 一般為1-2萬, 非持久化 2 萬以上),在生產(chǎn)環(huán)境中部署10個ActiveMQ就能達到10萬筆/秒以上的性能,部署越多的ActiveMQ broker 在MQ上latency也就越低,系統(tǒng)吞吐量也就越高。

本文轉(zhuǎn)載自28cm不含頭的《Kafka,Mq,Redis作為消息隊列使用時的差異?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內(nèi)容