多維度對比5款主流分佈式MQ消息隊列,媽媽不再擔憂個人技術選型了

一、引言

對於即時通信系統(包括IM、消息推送系統等)來講,MQ消息中件間是很是常見的基礎軟件,但市面上種類衆多、各有所長的MQ消息中件間產品,該怎麼去選擇?這是個問題!html

對於不少經驗不足的開發者來講,一個公司內部用的IM聊天系統,總用戶量也不過百十來人,動輒就是Kafka、MongoDB,美其名曰爲了高性能和可擴展性,真是大炮打蚊子。而對於中大型的即時通信場景來講,有的開發者確爲了貪圖使用簡單、資料全面,反而使用臃腫不堪的ActiveMQ,這就有點失去章法了。算法

唧唧歪歪這麼多,那什麼樣的場景到底該用哪一種MQ消息中件間產品合適?讀完本文您或許就有了答案。數據庫

本文將從17個維度綜合對比Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ這5款當前最主流的MQ消息中間件產品,但願能爲您的下一次產品的架構設計和MQ消息中間件選型提供參考依據。apache

學習交流:後端

  • 即時通信/推送技術開發交流4羣:101279154[推薦]
  • 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》

(本文同步發佈於:http://www.52im.net/thread-26...緩存

二、相關資料

官網地址:服務器

Kafka:http://kafka.apache.org/微信

RabbitMQ:https://www.rabbitmq.com/網絡

ZeroMQ:http://zeromq.org/多線程

RocketMQ:http://rocketmq.apache.org/

ActiveMQ:http://activemq.apache.org/

相關文章:

《IM開發基礎知識補課(五):通俗易懂,正確理解並用好MQ消息隊列》

《IM系統的MQ消息中間件選型:Kafka仍是RabbitMQ?》

三、維度1:資料文檔

1)Kafka:資料數量中等。有Kafka做者本身寫的書,網上資料也有一些。

2)RabbitMQ:資料數量多。有一些不錯的書,網上資料多。

3)ZeroMQ:資料數量少。專門寫ZeroMQ的書較少,網上的資料可能是一些代碼的實現和簡單介紹。

4)RocketMQ:資料數量少。專門寫RocketMQ的書目前有了兩本;網上的資料參差不齊,官方文檔很簡潔,可是對技術細節沒有過多的描述。

5)ActiveMQ:資料數量多。沒有專門寫ActiveMQ的書,網上資料多。

四、維度2:開發語言

1)Kafka:Scala

2)RabbitMQ:Erlang

3)ZeroMQ:C語言

4)RocketMQ:Java

5)ActiveMQ:Java

五、維度3:支持的協議

1)Kafka:本身定義的一套…(基於TCP)

2)RabbitMQ:AMQP

3)ZeroMQ:TCP、UDP

4)RocketMQ:本身定義的一套…

5)ActiveMQ:OpenWire、STOMP、REST、XMPP、AMQP

六、維度4:消息存儲

1)Kafka:

內存、磁盤、數據庫。支持大量堆積。

Kafka的最小存儲單元是分區,一個topic包含多個分區,Kafka建立主題時,這些分區會被分配在多個服務器上,一般一個broker一臺服務器。

分區首領會均勻地分佈在不一樣的服務器上,分區副本也會均勻的分佈在不一樣的服務器上,確保負載均衡和高可用性,當新的broker加入集羣的時候,部分副本會被移動到新的broker上。

根據配置文件中的目錄清單,Kafka會把新的分區分配給目錄清單裏分區數最少的目錄。

默認狀況下,分區器使用輪詢算法把消息均衡地分佈在同一個主題的不一樣分區中,對於發送時指定了key的狀況,會根據key的hashcode取模後的值存到對應的分區中。

2)RabbitMQ:

內存、磁盤。支持少許堆積。

RabbitMQ的消息分爲持久化的消息和非持久化消息,無論是持久化的消息仍是非持久化的消息均可以寫入到磁盤。

持久化的消息在到達隊列時就寫入到磁盤,而且若是能夠,持久化的消息也會在內存中保存一份備份,這樣能夠提升必定的性能,當內存吃緊的時候會從內存中清除。

非持久化的消息通常只存在於內存中,在內存吃緊的時候會被換入到磁盤中,以節省內存。

引入鏡像隊列機制,可將重要隊列「複製」到集羣中的其餘broker上,保證這些隊列的消息不會丟失。

配置鏡像的隊列,都包含一個主節點master和多個從節點slave,若是master失效,加入時間最長的slave會被提高爲新的master,除發送消息外的全部動做都向master發送,而後由master將命令執行結果廣播給各個slave,RabbitMQ會讓master均勻地分佈在不一樣的服務器上,而同一個隊列的slave也會均勻地分佈在不一樣的服務器上,保證負載均衡和高可用性。

3)ZeroMQ:

消息發送端的內存或者磁盤中。不支持持久化。

4)RocketMQ:

磁盤。支持大量堆積。

commitLog文件存放實際的消息數據,每一個commitLog上限是1G,滿了以後會自動新建一個commitLog文件保存數據。

ConsumeQueue隊列只存放offset、size、tagcode,很是小,分佈在多個broker上。

ConsumeQueue至關於CommitLog的索引文件,消費者消費時會從consumeQueue中查找消息在commitLog中的offset,再去commitLog中查找元數據。

ConsumeQueue存儲格式的特性,保證了寫過程的順序寫盤(寫CommitLog文件),大量數據IO都在順序寫同一個commitLog,滿1G了再寫新的。

加上RocketMQ是累計4K才強制從PageCache中刷到磁盤(緩存),因此高併發寫性能突出。

5)ActiveMQ:

內存、磁盤、數據庫。支持少許堆積。

七、維度5:消息事務

1)Kafka:支持

2)RabbitMQ:支持。客戶端將信道設置爲事務模式,只有當消息被RabbitMQ接收,事務才能提交成功,不然在捕獲異常後進行回滾。使用事務會使得性能有所降低

3)ZeroMQ:不支持

4)RocketMQ:支持

5)ActiveMQ:支持

八、維度6:負載均衡

8.1 Kafka
支持負載均衡。

1)一個broker一般就是一臺服務器節點。

對於同一個Topic的不一樣分區,Kafka會盡力將這些分區分佈到不一樣的Broker服務器上,zookeeper保存了broker、主題和分區的元數據信息。

分區首領會處理來自客戶端的生產請求,Kafka分區首領會被分配到不一樣的broker服務器上,讓不一樣的broker服務器共同分擔任務。

每個broker都緩存了元數據信息,客戶端能夠從任意一個broker獲取元數據信息並緩存起來,根據元數據信息知道要往哪裏發送請求。

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

3)當消費者加入或者退出消費者組的時候,還會觸發再均衡,爲每個消費者從新分配分區,分攤負載。

Kafka的負載均衡大部分是自動完成的,分區的建立也是Kafka完成的,隱藏了不少細節,避免了繁瑣的配置和人爲疏忽形成的負載問題。

4)發送端由topic和key來決定消息發往哪一個分區,若是key爲null,那麼會使用輪詢算法將消息均衡地發送到同一個topic的不一樣分區中。若是key不爲null,那麼會根據key的hashcode取模計算出要發往的分區。

8.2 RabbitMQ
對負載均衡的支持很差。

1)消息被投遞到哪一個隊列是由交換器和key決定的,交換器、路由鍵、隊列都須要手動建立。

RabbitMQ客戶端發送消息要和broker創建鏈接,須要事先知道broker上有哪些交換器,有哪些隊列。

一般要聲明要發送的目標隊列,若是沒有目標隊列,會在broker上建立一個隊列,若是有,就什麼都不處理,接着往這個隊列發送消息。假設大部分繁重任務的隊列都建立在同一個broker上,那麼這個broker的負載就會過大。

能夠在上線前預先建立隊列,無需聲明要發送的隊列,可是發送時不會嘗試建立隊列,可能出現找不到隊列的問題,RabbitMQ的備份交換器會把找不到隊列的消息保存到一個專門的隊列中,以便之後查詢使用。

使用鏡像隊列機制創建RabbitMQ集羣能夠解決這個問題,造成master-slave的架構,master節點會均勻分佈在不一樣的服務器上,讓每一臺服務器分攤負載。slave節點只是負責轉發,在master失效時會選擇加入時間最長的slave成爲master。

當新節點加入鏡像隊列的時候,隊列中的消息不會同步到新的slave中,除非調用同步命令,可是調用命令後,隊列會阻塞,不能在生產環境中調用同步命令。

2)當RabbitMQ隊列擁有多個消費者的時候,隊列收到的消息將以輪詢的分發方式發送給消費者。每條消息只會發送給訂閱列表裏的一個消費者,不會重複。

這種方式很是適合擴展,並且是專門爲併發程序設計的。

若是某些消費者的任務比較繁重,那麼能夠設置basicQos限制信道上消費者能保持的最大未確認消息的數量,在達到上限時,RabbitMQ再也不向這個消費者發送任何消息。

3)對於RabbitMQ而言,客戶端與集羣創建的TCP鏈接不是與集羣中全部的節點創建鏈接,而是挑選其中一個節點創建鏈接。

可是RabbitMQ集羣能夠藉助HAProxy、LVS技術,或者在客戶端使用算法實現負載均衡,引入負載均衡以後,各個客戶端的鏈接能夠分攤到集羣的各個節點之中。

客戶端均衡算法:

a. 輪詢法:按順序返回下一個服務器的鏈接地址。

b. 加權輪詢法:給配置高、負載低的機器配置更高的權重,讓其處理更多的請求;而配置低、負載高的機器,給其分配較低的權重,下降其系統負載。

c. 隨機法:隨機選取一個服務器的鏈接地址。

d. 加權隨機法:按照機率隨機選取鏈接地址。

e. 源地址哈希法:經過哈希函數計算獲得的一個數值,用該數值對服務器列表的大小進行取模運算。

f. 最小鏈接數法:動態選擇當前鏈接數最少的一臺服務器的鏈接地址。

8.3 ZeroMQ
去中心化,不支持負載均衡。自己只是一個多線程網絡庫。

8.4 RocketMQ
支持負載均衡。

一個broker一般是一個服務器節點,broker分爲master和slave,master和slave存儲的數據同樣,slave從master同步數據。

1)nameserver與每一個集羣成員保持心跳,保存着Topic-Broker路由信息,同一個topic的隊列會分佈在不一樣的服務器上。

2)發送消息經過輪詢隊列的方式發送,每一個隊列接收平均的消息量。發送消息指定topic、tags、keys,沒法指定投遞到哪一個隊列(沒有意義,集羣消費和廣播消費跟消息存放在哪一個隊列沒有關係)。

tags選填,相似於 Gmail 爲每封郵件設置的標籤,方便服務器過濾使用。目前只支 持每一個消息設置一個 tag,因此也能夠類比爲 Notify 的 MessageType 概念。

keys選填,表明這條消息的業務關鍵詞,服務器會根據 keys 建立哈希索引,設置後, 能夠在 Console 系統根據 Topic、Keys 來查詢消息,因爲是哈希索引,請儘量 保證 key 惟一,例如訂單號,商品 Id 等。

3)RocketMQ的負載均衡策略規定:

Consumer數量應該小於等於Queue數量,若是Consumer超過Queue數量,那麼多餘的Consumer 將不能消費消息。

這一點和Kafka是一致的,RocketMQ會盡量地爲每個Consumer分配相同數量的隊列,分攤負載。

8.5 ActiveMQ
支持負載均衡。能夠基於zookeeper實現負載均衡。

九、維度7:集羣方式

1)Kafka:

自然的‘Leader-Slave’無狀態集羣,每臺服務器既是Master也是Slave。

分區首領均勻地分佈在不一樣的Kafka服務器上,分區副本也均勻地分佈在不一樣的Kafka服務器上,因此每一臺Kafka服務器既含有分區首領,同時又含有分區副本。

每一臺Kafka服務器是某一臺Kafka服務器的Slave,同時也是某一臺Kafka服務器的leader。

Kafka的集羣依賴於zookeeper,zookeeper支持熱擴展,全部的broker、消費者、分區均可以動態加入移除,而無需關閉服務,與不依靠zookeeper集羣的mq相比,這是最大的優點。

2)RabbitMQ:

支持簡單集羣,'複製'模式,對高級集羣模式支持很差。

RabbitMQ的每個節點,無論是單一節點系統或者是集羣中的一部分,要麼是內存節點,要麼是磁盤節點,集羣中至少要有一個是磁盤節點。

在RabbitMQ集羣中建立隊列,集羣只會在單個節點建立隊列進程和完整的隊列信息(元數據、狀態、內容),而不是在全部節點上建立。

引入鏡像隊列,能夠避免單點故障,確保服務的可用性,可是須要人爲地爲某些重要的隊列配置鏡像。

3)ZeroMQ:

去中心化,不支持集羣。

4)RocketMQ:

經常使用 多對'Master-Slave' 模式,開源版本需手動切換Slave變成Master。

Name Server是一個幾乎無狀態節點,可集羣部署,節點之間無任何信息同步。

Broker部署相對複雜,Broker分爲Master與Slave,一個Master能夠對應多個Slave,可是一個Slave只能對應一個Master。

Master與Slave的對應關係經過指定相同的BrokerName,不一樣的BrokerId來定義,BrokerId爲0表示Master,非0表示Slave。

Master也能夠部署多個。每一個Broker與Name Server集羣中的全部節點創建長鏈接,定時註冊Topic信息到全部Name Server。

Producer與Name Server集羣中的其中一個節點(隨機選擇)創建長鏈接,按期從Name Server取Topic路由信息,並向提供Topic服務的Master創建長鏈接,且定時向Master發送心跳。Producer徹底無狀態,可集羣部署。

Consumer與Name Server集羣中的其中一個節點(隨機選擇)創建長鏈接,按期從Name Server取Topic路由信息,並向提供Topic服務的Master、Slave創建長鏈接,且定時向Master、Slave發送心跳。

Consumer既能夠從Master訂閱消息,也能夠從Slave訂閱消息,訂閱規則由Broker配置決定。

客戶端先找到NameServer, 而後經過NameServer再找到 Broker。

一個topic有多個隊列,這些隊列會均勻地分佈在不一樣的broker服務器上。RocketMQ隊列的概念和Kafka的分區概念是基本一致的,Kafka同一個topic的分區儘量地分佈在不一樣的broker上,分區副本也會分佈在不一樣的broker上。

RocketMQ集羣的slave會從master拉取數據備份,master分佈在不一樣的broker上。

5)ActiveMQ:

支持簡單集羣模式,好比'主-備',對高級集羣模式支持很差。

十、維度8:管理界面

1)Kafka:通常

2)RabbitMQ:好

3)ZeroMQ:無

4)RocketMQ:有管理後臺, 但不是項目裏自帶, 須要本身啓動一個單獨的管理後臺實例

5)ActiveMQ:通常

十一、維度9:可用性

1)Kafka:很是高(分佈式)

2)RabbitMQ:高(主從)

3)ZeroMQ:高

4)RocketMQ:很是高(分佈式)

5)ActiveMQ:高(主從)

十二、維度10:消息重複

1)Kafka:支持at least once、at most once

2)RabbitMQ:支持at least once、at most once

3)ZeroMQ:只有重傳機制,可是沒有持久化,消息丟了重傳也沒有用。既不是at least once、也不是at most once、更不是exactly only once

4)RocketMQ:支持at least once

5)ActiveMQ:支持at least once

1三、維度11:吞吐量TPS

1)Kafka:極大。Kafka按批次發送消息和消費消息。發送端將多個小消息合併,批量發向Broker,消費端每次取出一個批次的消息批量處理。

2)RabbitMQ:比較大

3)ZeroMQ:極大

4)RocketMQ:大。RocketMQ接收端能夠批量消費消息,能夠配置每次消費的消息數,可是發送端不是批量發送。

5)ActiveMQ:比較大

1四、維度12:訂閱形式和消息分發

14.1 Kafka
基於topic以及按照topic進行正則匹配的發佈訂閱模式。

1)發送:

發送端由topic和key來決定消息發往哪一個分區,若是key爲null,那麼會使用輪詢算法將消息均衡地發送到同一個topic的不一樣分區中。若是key不爲null,那麼會根據key的hashcode取模計算出要發往的分區。

2)接收:

consumer向羣組協調器broker發送心跳來維持他們和羣組的從屬關係以及他們對分區的全部權關係,全部權關係一旦被分配就不會改變除非發生再均衡(好比有一個consumer加入或者離開consumer group),consumer只會從對應的分區讀取消息。

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

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

14.2 RabbitMQ
提供了4種:direct、topic、Headers和fanout。

1)發送:

先要聲明一個隊列,這個隊列會被建立或者已經被建立,隊列是基本存儲單元。

由exchange和key決定消息存儲在哪一個隊列。

direct>發送到和bindingKey徹底匹配的隊列。

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

fanout>與key無關,會發送到全部和exchange綁定的隊列

headers>與key無關,消息內容的headers屬性(一個鍵值對)和綁定鍵值對徹底匹配時,會發送到此隊列。此方式性能低通常不用

2)接收:

RabbitMQ的隊列是基本存儲單元,再也不被分區或者分片,對於咱們已經建立了的隊列,消費端要指定從哪個隊列接收消息。

當RabbitMQ隊列擁有多個消費者的時候,隊列收到的消息將以輪詢的分發方式發送給消費者。每條消息只會發送給訂閱列表裏的一個消費者,不會重複。

這種方式很是適合擴展,並且是專門爲併發程序設計的。

若是某些消費者的任務比較繁重,那麼能夠設置basicQos限制信道上消費者能保持的最大未確認消息的數量,在達到上限時,RabbitMQ再也不向這個消費者發送任何消息。

14.3 ZeroMQ
點對點(p2p)。

14.4 RocketMQ
基於topic/messageTag以及按照消息類型、屬性進行正則匹配的發佈訂閱模式。

1)發送:

發送消息經過輪詢隊列的方式發送,每一個隊列接收平均的消息量。發送消息指定topic、tags、keys,沒法指定投遞到哪一個隊列(沒有意義,集羣消費和廣播消費跟消息存放在哪一個隊列沒有關係)。

tags選填,相似於 Gmail 爲每封郵件設置的標籤,方便服務器過濾使用。目前只支 持每一個消息設置一個 tag,因此也能夠類比爲 Notify 的 MessageType 概念。

keys選填,表明這條消息的業務關鍵詞,服務器會根據 keys 建立哈希索引,設置後, 能夠在 Console 系統根據 Topic、Keys 來查詢消息,因爲是哈希索引,請儘量 保證 key 惟一,例如訂單號,商品 Id 等。

2)接收:

廣播消費。一條消息被多個Consumer消費,即便Consumer屬於同一個ConsumerGroup,消息也會被ConsumerGroup中的每一個Consumer都消費一次。

集羣消費。一個 Consumer Group中的Consumer實例平均分攤消費消息。例如某個Topic有 9 條消息,其中一個Consumer Group有3個實例,那麼每一個實例只消費其中的 3 條消息。即每個隊列都把消息輪流分發給每一個consumer。

14.5 ActiveMQ
點對點(p2p)、廣播(發佈-訂閱)。

點對點模式,每一個消息只有1個消費者;發佈/訂閱模式,每一個消息能夠有多個消費者。

1)發送:

點對點模式:先要指定一個隊列,這個隊列會被建立或者已經被建立。

發佈/訂閱模式:先要指定一個topic,這個topic會被建立或者已經被建立。

2)接收:

點對點模式:對於已經建立了的隊列,消費端要指定從哪個隊列接收消息。

發佈/訂閱模式:對於已經建立了的topic,消費端要指定訂閱哪個topic的消息。

1五、維度13:順序消息

Kafka:支持。

設置生產者的max.in.flight.requests.per.connection爲1,能夠保證消息是按照發送順序寫入服務器的,即便發生了重試。

Kafka保證同一個分區裏的消息是有序的,可是這種有序分兩種狀況:

①key爲null,消息逐個被寫入不一樣主機的分區中,可是對於每一個分區依然是有序的

②key不爲null , 消息被寫入到同一個分區,這個分區的消息都是有序。

RabbitMQ:不支持

ZeroMQ:不支持

RocketMQ:支持

ActiveMQ:不支持

1六、維度14:消息確認

16.1 Kafka
支持。

1)發送方確認機制:

ack=0,無論消息是否成功寫入分區

ack=1,消息成功寫入首領分區後,返回成功

ack=all,消息成功寫入全部分區後,返回成功。

2)接收方確認機制:

自動或者手動提交分區偏移量,早期版本的Kafka偏移量是提交給Zookeeper的,這樣使得zookeeper的壓力比較大,更新版本的Kafka的偏移量是提交給Kafka服務器的,再也不依賴於zookeeper羣組,集羣的性能更加穩定。

16.2 RabbitMQ
支持。

1)發送方確認機制,消息被投遞到全部匹配的隊列後,返回成功。若是消息和隊列是可持久化的,那麼在寫入磁盤後,返回成功。支持批量確認和異步確認。

2)接收方確認機制,設置autoAck爲false,須要顯式確認,設置autoAck爲true,自動確認。

當autoAck爲false的時候,RabbitMQ隊列會分紅兩部分,一部分是等待投遞給consumer的消息,一部分是已經投遞可是沒收到確認的消息。

若是一直沒有收到確認信號,而且consumer已經斷開鏈接,RabbitMQ會安排這個消息從新進入隊列,投遞給原來的消費者或者下一個消費者。

未確認的消息不會有過時時間,若是一直沒有確認,而且沒有斷開鏈接,RabbitMQ會一直等待,RabbitMQ容許一條消息處理的時間能夠好久好久。

16.3 ZeroMQ
支持。

16.4 RocketMQ
支持。

16.5 ActiveMQ
支持。

1七、維度15:消息回溯

1)Kafka:支持指定分區offset位置的回溯

2)RabbitMQ:不支持

3)ZeroMQ:不支持

4)RocketMQ:支持指定時間點的回溯

5)ActiveMQ:不支持

1八、維度16:消息重試

18.1 Kafka
不支持,可是能夠實現。

Kafka支持指定分區offset位置的回溯,能夠實現消息重試。

18.2 RabbitMQ
不支持,可是能夠利用消息確認機制實現。

RabbitMQ接收方確認機制,設置autoAck爲false。

當autoAck爲false的時候,RabbitMQ隊列會分紅兩部分,一部分是等待投遞給consumer的消息,一部分是已經投遞可是沒收到確認的消息。

若是一直沒有收到確認信號,而且consumer已經斷開鏈接,RabbitMQ會安排這個消息從新進入隊列,投遞給原來的消費者或者下一個消費者。

18.3 ZeroMQ
不支持。

18.4 RocketMQ
支持。

消息消費失敗的大部分場景下,當即重試99%都會失敗,因此RocketMQ的策略是在消費失敗時定時重試,每次時間間隔相同。

1)發送端的 send 方法自己支持內部重試,重試邏輯以下:

至多重試3次;

若是發送失敗,則輪轉到下一個broker;

這個方法的總耗時不超過sendMsgTimeout 設置的值,默認 10s,超過期間不在重試。

2)接收端:

Consumer 消費消息失敗後,要提供一種重試機制,令消息再消費一次。Consumer 消費消息失敗一般能夠分爲如下兩種狀況:

因爲消息自己的緣由,例如反序列化失敗,消息數據自己沒法處理(例如話費充值,當前消息的手機號被註銷,沒法充值)等。定時重試機制,好比過 10s 秒後再重試。

因爲依賴的下游應用服務不可用,例如 db 鏈接不可用,外系統網絡不可達等。即便跳過當前失敗的消息,消費其餘消息一樣也會報錯。這種狀況能夠 sleep 30s,再消費下一條消息,減輕 Broker 重試消息的壓力。

18.5 ActiveMQ
不支持。

1九、維度17:併發度

19.1 Kafka
併發度高。

一個線程一個消費者,Kafka限制消費者的個數要小於等於分區數,若是要提升並行度,能夠在消費者中再開啓多線程,或者增長consumer實例數量。

19.2 RabbitMQ
併發度極高。自己是用Erlang語言寫的,併發性能高。

可在消費者中開啓多線程,最經常使用的作法是一個channel對應一個消費者,每個線程把持一個channel,多個線程複用connection的tcp鏈接,減小性能開銷。

當RabbitMQ隊列擁有多個消費者的時候,隊列收到的消息將以輪詢的分發方式發送給消費者。每條消息只會發送給訂閱列表裏的一個消費者,不會重複。

這種方式很是適合擴展,並且是專門爲併發程序設計的。

若是某些消費者的任務比較繁重,那麼能夠設置basicQos限制信道上消費者能保持的最大未確認消息的數量,在達到上限時,RabbitMQ再也不向這個消費者發送任何消息。

19.3 ZeroMQ
併發度高。

19.4 RocketMQ
併發度高。

1)RocketMQ限制消費者的個數少於等於隊列數,可是能夠在消費者中再開啓多線程,這一點和Kafka是一致的,提升並行度的方法相同。

修改消費並行度方法:

同一個 ConsumerGroup 下,經過增長 Consumer 實例數量來提升並行度,超過訂閱隊列數的 Consumer實例無效。

提升單個 Consumer 的消費並行線程,經過修改參數consumeThreadMin、consumeThreadMax

2)同一個網絡鏈接connection,客戶端多個線程能夠同時發送請求,鏈接會被複用,減小性能開銷。

19.5 ActiveMQ
併發度高。

單個ActiveMQ的接收和消費消息的速度在1萬筆/秒(持久化 通常爲1-2萬, 非持久化 2 萬以上),在生產環境中部署10個ActiveMQ就能達到10萬筆/秒以上的性能,部署越多的ActiveMQ broker 在MQ上latency也就越低,系統吞吐量也就越高。

附錄:更多架構設計方面的文章

[1] 有關IM架構設計的文章:

《淺談IM系統的架構設計》

《簡述移動端IM開發的那些坑:架構設計、通訊協議和客戶端》

《一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文)》

《一套原創分佈式即時通信(IM)系統理論架構方案》

《從零到卓越:京東客服即時通信系統的技術架構演進歷程》

《蘑菇街即時通信/IM服務器開發之架構選擇》

《騰訊QQ1.4億在線用戶的技術挑戰和架構演進之路PPT》

《微信後臺基於時間序的海量數據冷熱分級架構設計實踐》

《微信技術總監談架構:微信之道——大道至簡(演講全文)》

《如何解讀《微信技術總監談架構:微信之道——大道至簡》》

《快速裂變:見證微信強大後臺架構從0到1的演進歷程(一)》

《17年的實踐:騰訊海量產品的技術方法論》

《移動端IM中大規模羣消息的推送如何保證效率、實時性?》

《現代IM系統中聊天消息的同步和存儲方案探討》

《IM開發基礎知識補課(二):如何設計大量圖片文件的服務端存儲架構?》

《IM開發基礎知識補課(三):快速理解服務端數據庫讀寫分離原理及實踐建議》

《IM開發基礎知識補課(四):正確理解HTTP短鏈接中的Cookie、Session和Token》

《WhatsApp技術實踐分享:32人工程團隊創造的技術神話》

《微信朋友圈千億訪問量背後的技術挑戰和實踐總結》

《王者榮耀2億用戶量的背後:產品定位、技術架構、網絡方案等》

《IM系統的MQ消息中間件選型:Kafka仍是RabbitMQ?》

《騰訊資深架構師乾貨總結:一文讀懂大型分佈式系統設計的方方面面》

《以微博類應用場景爲例,總結海量社交系統的架構設計步驟》

《快速理解高性能HTTP服務端的負載均衡技術原理》

《子彈短信光鮮的背後:網易雲信首席架構師分享億級IM平臺的技術實踐》

《知乎技術分享:從單機到2000萬QPS併發的Redis高性能緩存實踐之路》

《IM開發基礎知識補課(五):通俗易懂,正確理解並用好MQ消息隊列》

《微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)》

《微信技術分享:微信的海量IM聊天消息序列號生成實踐(容災方案篇)》

《新手入門:零基礎理解大型分佈式架構的演進歷史、技術原理、最佳實踐》

《一套高可用、易伸縮、高併發的IM羣聊、單聊架構方案設計實踐》

《阿里技術分享:深度揭祕阿里數據庫技術方案的10年變遷史》

《阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路》

《社交軟件紅包技術解密(一):全面解密QQ紅包技術方案——架構、技術實現等》

《社交軟件紅包技術解密(二):解密微信搖一搖紅包從0到1的技術演進》

《社交軟件紅包技術解密(三):微信搖一搖紅包雨背後的技術細節》

《社交軟件紅包技術解密(四):微信紅包系統是如何應對高併發的》

《社交軟件紅包技術解密(五):微信紅包系統是如何實現高可用性的》

《社交軟件紅包技術解密(六):微信紅包系統的存儲層架構演進實踐》

《社交軟件紅包技術解密(七):支付寶紅包的海量高併發技術實踐》

《社交軟件紅包技術解密(八):全面解密微博紅包技術方案》

《社交軟件紅包技術解密(九):談談手Q紅包的功能邏輯、容災、運維、架構等》

《即時通信新手入門:一文讀懂什麼是Nginx?它可否實現IM的負載均衡?》

《即時通信新手入門:快速理解RPC技術——基本概念、原理和用途》

《多維度對比5款主流分佈式MQ消息隊列,媽媽不再擔憂個人技術選型了》

更多同類文章 ……

[2] 更多其它架構設計相關文章:

《騰訊資深架構師乾貨總結:一文讀懂大型分佈式系統設計的方方面面》

《快速理解高性能HTTP服務端的負載均衡技術原理》

《子彈短信光鮮的背後:網易雲信首席架構師分享億級IM平臺的技術實踐》

《知乎技術分享:從單機到2000萬QPS併發的Redis高性能緩存實踐之路》

《新手入門:零基礎理解大型分佈式架構的演進歷史、技術原理、最佳實踐》

《阿里技術分享:深度揭祕阿里數據庫技術方案的10年變遷史》

《阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路》

《達達O2O後臺架構演進實踐:從0到4000高併發請求背後的努力》

《優秀後端架構師必會知識:史上最全MySQL大表優化方案總結》

《小米技術分享:解密小米搶購系統千萬高併發架構的演進和實踐》

《一篇讀懂分佈式架構下的負載均衡技術:分類、原理、算法、常見方案等》

《通俗易懂:如何設計能支撐百萬併發的數據庫架構?》

《多維度對比5款主流分佈式MQ消息隊列,媽媽不再擔憂個人技術選型了》

更多同類文章 ……

(本文同步發佈於:http://www.52im.net/thread-26...

相關文章
相關標籤/搜索