Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 497, comments - 13, trackbacks - 0, articles - 1

          導航

          公告


            ① 即時通訊開發社區
            地址: 52im.net
            專業的資料、社區

            ② 關注我的公眾號:

            讓技術不再封閉

            ③ 我的Github
            地址: 點此進入
            好代碼,與大家分享
          <2019年6月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          常用鏈接

          留言簿(286)

          隨筆檔案

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          60天內閱讀排行

          1、引言

          對于即時通訊網來說,所有的技術文章和資料都在圍繞即時通訊這個技術方向進行整理和分享,這一次也不例外。對于即時通訊系統(包括IM、消息推送系統等)來說,MQ消息中件間是非常常見的基礎軟件,但市面上種類眾多、各有所長的MQ消息中件間產品,該怎么去選擇?這是個問題!

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

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

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

          學習交流:

          - 即時通訊/推送技術開發交流4群:101279154[推薦]

          - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

          (本文同步發布于:http://www.52im.net/thread-2625-1-1.html

          2、相關資料

          官網地址:


          相關文章:

          3、維度1:資料文檔

          1)Kafka:資料數量中等。有Kafka作者自己寫的書,網上資料也有一些。

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

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

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

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

          4、維度2:開發語言

          1)Kafka:Scala

          2)RabbitMQ:Erlang

          3)ZeroMQ:C語言

          4)RocketMQ:Java

          5)ActiveMQ:Java

          5、維度3:支持的協議

          1)Kafka:自己定義的一套…(基于TCP)

          2)RabbitMQ:AMQP

          3)ZeroMQ:TCP、UDP

          4)RocketMQ:自己定義的一套…

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

          6、維度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:

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

          7、維度5:消息事務

          1)Kafka:支持

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

          3)ZeroMQ:不支持

          4)RocketMQ:支持

          5)ActiveMQ:支持

          8、維度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實現負載均衡。

          9、維度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:

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

          10、維度8:管理界面

          1)Kafka:一般

          2)RabbitMQ:好

          3)ZeroMQ:無

          4)RocketMQ:有管理后臺, 但不是項目里自帶, 需要自己啟動一個單獨的管理后臺實例

          5)ActiveMQ:一般

          11、維度9:可用性

          1)Kafka:非常高(分布式)

          2)RabbitMQ:高(主從)

          3)ZeroMQ:高

          4)RocketMQ:非常高(分布式)

          5)ActiveMQ:高(主從)

          12、維度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

          13、維度11:吞吐量TPS

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

          2)RabbitMQ:比較大

          3)ZeroMQ:極大

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

          5)ActiveMQ:比較大

          14、維度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的消息。

          15、維度13:順序消息

          Kafka:支持。

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

          Kafka保證同一個分區里的消息是有序的,但是這種有序分兩種情況:

          ①key為null,消息逐個被寫入不同主機的分區中,但是對于每個分區依然是有序的

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

          RabbitMQ:不支持

          ZeroMQ:不支持

          RocketMQ:支持

          ActiveMQ:不支持

          16、維度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

          支持。

          17、維度15:消息回溯

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

          2)RabbitMQ:不支持

          3)ZeroMQ:不支持

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

          5)ActiveMQ:不支持

          18、維度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

          不支持。

          19、維度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-2625-1-1.html



          作者:Jack Jiang (點擊作者姓名進入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時通訊開發交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 九龙县| 汝阳县| 巴林左旗| 卢湾区| 北票市| 游戏| 铅山县| 宁强县| 卓资县| 淅川县| 邻水| 安康市| 肥西县| 义马市| 江津市| 扶风县| 绥德县| 白银市| 密山市| 铜山县| 交城县| 通许县| 巴彦淖尔市| 东阿县| 漳浦县| 江山市| 玉田县| 韩城市| 繁昌县| 桓仁| 于都县| 泸西县| 海伦市| 万源市| 新河县| 盐城市| 新泰市| 师宗县| 昂仁县| 卓资县| 兴和县|