該如何選擇消息隊列?

在高併發業務場景下,消息隊列在流量削峯、解耦上有不可替代的做用。當前使用較多的消息隊列有 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、Pulsar 等。編程

消息隊列這麼多,到底該選擇哪款消息隊列呢?併發

選擇消息隊列的基本標準

雖然這些消息隊列在功能和特性方面各有優劣,但咱們在選擇的時候要有一個基本標準。異步

首先,必須是開源的產品。開源意味着,若是有一天你使用的消息隊列遇到了一個影響你係統業務的 Bug,至少還有機會經過修改源代碼來迅速修復或規避這個 Bug,解決你的系統的問題,而不是等待開發者發佈的下一個版原本解決。編程語言

其次,這個產品必須是近年來比較流行而且有必定社區活躍度的產品。流行的好處是,只要使用場景不太冷門,遇到 Bug 的機率會很是低,由於大部分遇到的 Bug,其餘人早就遇到而且修復了。在使用過程當中遇到的一些問題,也比較容易在網上搜索到相似的問題,而後很快的找到解決方案。還有一個優點就是,流行的產品與周邊生態系統會有一個比較好的集成和兼容。分佈式

最後,做爲一款及格的消息隊列,必須具有的幾個特性包括:高併發

  • 消息的可靠傳遞:確保不丟消息;
  • Cluster:支持集羣,確保不會由於某個節點宕機致使服務不可用,固然也不能丟消息;
  • 性能:具有足夠好的性能,能知足絕大多數場景的性能要求。

接下來看一下有哪些符合上面這些條件,可供選擇的開源消息隊列。性能

RabbitMQ

RabbitMQ

首先,咱們來看下消息隊列 RabbitMQ。RabbitMQ 於 2007 年發佈,是使用 Erlang 編程語言編寫的,最先是爲電信行業系統之間的可靠通訊設計的,也是少數幾個支持 AMQP 協議的消息隊列之一。大數據

RabbitMQ:輕量級、迅捷,它的宣傳口號,也很明確地代表了 RabbitMQ 的特色:Messaging that just works,開箱即用的消息隊列。也就是說,RabbitMQ 是一個至關輕量級的消息隊列,很是容易部署和使用。優化

RabbitMQ 一個比較有特點的功能是支持很是靈活的路由配置,和其餘消息隊列不一樣的是,它在生產者(Producer)和隊列(Queue)之間增長了一個 Exchange 模塊,能夠理解爲交換機。設計

Exchange 模塊的做用和交換機很是類似,根據配置的路由規則將生產者發出的消息分發到不一樣的隊列中。路由的規則也很是靈活,甚至能夠本身來實現路由規則。若是正好須要這個功能,RabbitMQ 是個不錯的選擇。

RabbitMQ 的客戶端支持的編程語言大概是全部消息隊列中最多的。

接下來講下 RabbitMQ 的幾個問題:

  1. RabbitMQ 對消息堆積的支持並很差,當大量消息積壓的時候,會致使 RabbitMQ 的性能急劇降低。
  2. RabbitMQ 的性能是這幾個消息隊列中最差的,大概每秒鐘能夠處理幾萬到十幾萬條消息。若是應用對消息隊列的性能要求很是高,那不要選擇 RabbitMQ。
  3. RabbitMQ 使用的編程語言 Erlang,擴展和二次開發成本高。

RocketMQ

RocketMQ

RocketMQ 是阿里巴巴在 2012 年開源的消息隊列產品,用 Java 語言實現,在設計時參考了 Kafka,並作出了本身的一些改進,後來捐贈給 Apache 軟件基金會,2017 正式畢業,成爲 Apache 的頂級項目。RocketMQ 在阿里內部被普遍應用在訂單,交易,充值,流計算,消息推送,日誌流式處理,Binglog 分發等場景。經歷過屢次雙十一考驗,它的性能、穩定性和可靠性都是值得信賴的。

RocketMQ 有着不錯的性能,穩定性和可靠性,具有一個現代的消息隊列應該有的幾乎所有功能和特性,而且它還在持續的成長中。

RocketMQ 有很是活躍的中文社區,大多數問題能夠找到中文的答案。RocketMQ 使用 Java 語言開發,源代碼相對比較容易讀懂,容易對 RocketMQ 進行擴展或者二次開發。

RocketMQ 對在線業務的響應時延作了不少的優化,大多數狀況下能夠作到毫秒級的響應,若是你的應用場景很在乎響應時延,那應該選擇使用 RocketMQ。

RocketMQ 的性能比 RabbitMQ 要高一個數量級,每秒鐘大概能處理幾十萬條消息。

RocketMQ 的劣勢是與周邊生態系統的集成和兼容程度不夠。

Kafka

Kafka

Apache Kafka 是一個分佈式消息發佈訂閱系統。它最初由 LinkedIn 公司基於獨特的設計實現爲一個分佈式的日誌提交系統,以後成爲 Apache 項目的一部分。

在早期的版本中,爲了得到極致的性能,在設計方面作了不少的犧牲,好比不保證消息的可靠性,可能會丟失消息,也不支持集羣,功能上也比較簡陋,這些犧牲對於處理海量日誌這個特定的場景都是能夠接受的。

可是,隨後幾年 Kafka 逐步補齊了這些短板,當下的 Kafka 已經發展爲一個很是成熟的消息隊列產品,不管在數據可靠性、穩定性和功能特性等方面均可以知足絕大多數場景的需求。

Kafka 與周邊生態系統的兼容性是最好的沒有之一,尤爲在大數據和流計算領域,幾乎全部的相關開源軟件系統都會優先支持 Kafka。

Kafka 性能高效、可擴展良好而且可持久化。它的分區特性,可複製和可容錯都是不錯的特性。

Kafka 使用 Scala 和 Java 語言開發,設計上大量使用了批量和異步的思想,使得 Kafka 能作到超高的性能。Kafka 的性能,尤爲是異步收發的性能,是三者中最好的,但與 RocketMQ 並無量級上的差別,大約每秒鐘能夠處理幾十萬條消息。

在有足夠的客戶端併發進行異步批量發送,而且開啓壓縮的狀況下,Kafka 的極限處理能力能夠超過每秒 2000 萬條消息。

可是 Kafka 異步批量的設計帶來的問題是,它的同步收發消息的響應時延比較高,由於當客戶端發送一條消息的時候,Kafka 並不會當即發送出去,而是要等一下子攢一批再發送,在它的 Broker 中,不少地方都會使用這種先攢一波再一塊兒處理的設計。當你的業務場景中,每秒鐘消息數量沒有那麼多的時候,Kafka 的時延反而會比較高。因此,Kafka 不太適合在線業務場景。

消息隊列對比

Kafka RocketMQ RabbitMQ
單機吞吐量 十萬級 十萬級 萬級
開發語言 Java & Scala Java Erlang
消息延遲 毫秒級 毫秒級 微秒級
消息丟失 參數優化配置後可作到0丟失 參數優化配置後可作到0丟失 有較低的機率丟失
消費模式 Pull Pull+Push Pull+Push
topic數量對吞吐量的影響 topic達到幾十,幾百個時,吞吐量會大幅度降低 topic達到幾百,幾千個時,吞吐量會有較小幅度的降低 \
可用性 很是高(分佈式) 很是高(主從) 高(主從)
總結 吞吐量高,微秒級延時,分佈式高可用,最好是支持較少topic數量,會有消息重複現象 可支撐大規模topic數量,方便二次開發和擴展 不支持集羣動態擴容,擴展和二次開發難

總結

本文分別介紹了 RabbitMQ,RocketMQ 和 Kafka 幾種常見的消息隊列,闡述了各類消息隊列的主要特色和優劣勢。

在瞭解了上面這些開源消息隊列各自的特色和優劣勢後,對於消息隊列及相關技術選型,相信你會有更深刻的理解和認識。如下幾條選擇的建議能夠參考:

  • 若是消息隊列不是將要構建系統的重點,對消息隊列功能和性能沒有很高的要求,只須要一個快速上手易於維護的消息隊列,建議使用 RabbitMQ。
  • 若是系統使用消息隊列主要場景是處理在線業務,好比在交易系統中用消息隊列傳遞訂單,須要低延遲和高穩定性,建議使用 RocketMQ。
  • 若是須要處理海量的消息,像收集日誌、監控信息或是埋點這類數據,或是你的應用場景大量使用了大數據、流計算相關的開源產品,那 Kafka 是最適合的消息隊列。

每個消息隊列都有本身的優劣勢,須要根據現有系統的狀況,選擇最適合的消息隊列,更多細節和原理性的東西,還需在實踐中見真知!

參考

1t.click/aA3A

相關文章
相關標籤/搜索