在高併發業務場景下,消息隊列在流量削峯、解耦上有不可替代的做用。當前使用較多的消息隊列有 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、Pulsar 等。編程
消息隊列這麼多,到底該選擇哪款消息隊列呢?併發
雖然這些消息隊列在功能和特性方面各有優劣,但咱們在選擇的時候要有一個基本標準。異步
首先,必須是開源的產品。開源意味着,若是有一天你使用的消息隊列遇到了一個影響你係統業務的 Bug,至少還有機會經過修改源代碼來迅速修復或規避這個 Bug,解決你的系統的問題,而不是等待開發者發佈的下一個版原本解決。編程語言
其次,這個產品必須是近年來比較流行而且有必定社區活躍度的產品。流行的好處是,只要使用場景不太冷門,遇到 Bug 的機率會很是低,由於大部分遇到的 Bug,其餘人早就遇到而且修復了。在使用過程當中遇到的一些問題,也比較容易在網上搜索到相似的問題,而後很快的找到解決方案。還有一個優點就是,流行的產品與周邊生態系統會有一個比較好的集成和兼容。分佈式
最後,做爲一款及格的消息隊列,必須具有的幾個特性包括:高併發
接下來看一下有哪些符合上面這些條件,可供選擇的開源消息隊列。性能
首先,咱們來看下消息隊列 RabbitMQ。RabbitMQ 於 2007 年發佈,是使用 Erlang 編程語言編寫的,最先是爲電信行業系統之間的可靠通訊設計的,也是少數幾個支持 AMQP 協議的消息隊列之一。大數據
RabbitMQ:輕量級、迅捷,它的宣傳口號,也很明確地代表了 RabbitMQ 的特色:Messaging that just works,開箱即用的消息隊列。也就是說,RabbitMQ 是一個至關輕量級的消息隊列,很是容易部署和使用。優化
RabbitMQ 一個比較有特點的功能是支持很是靈活的路由配置,和其餘消息隊列不一樣的是,它在生產者(Producer)和隊列(Queue)之間增長了一個 Exchange 模塊,能夠理解爲交換機。設計
Exchange 模塊的做用和交換機很是類似,根據配置的路由規則將生產者發出的消息分發到不一樣的隊列中。路由的規則也很是靈活,甚至能夠本身來實現路由規則。若是正好須要這個功能,RabbitMQ 是個不錯的選擇。
RabbitMQ 的客戶端支持的編程語言大概是全部消息隊列中最多的。
接下來講下 RabbitMQ 的幾個問題:
RocketMQ 是阿里巴巴在 2012 年開源的消息隊列產品,用 Java 語言實現,在設計時參考了 Kafka,並作出了本身的一些改進,後來捐贈給 Apache 軟件基金會,2017 正式畢業,成爲 Apache 的頂級項目。RocketMQ 在阿里內部被普遍應用在訂單,交易,充值,流計算,消息推送,日誌流式處理,Binglog 分發等場景。經歷過屢次雙十一考驗,它的性能、穩定性和可靠性都是值得信賴的。
RocketMQ 有着不錯的性能,穩定性和可靠性,具有一個現代的消息隊列應該有的幾乎所有功能和特性,而且它還在持續的成長中。
RocketMQ 有很是活躍的中文社區,大多數問題能夠找到中文的答案。RocketMQ 使用 Java 語言開發,源代碼相對比較容易讀懂,容易對 RocketMQ 進行擴展或者二次開發。
RocketMQ 對在線業務的響應時延作了不少的優化,大多數狀況下能夠作到毫秒級的響應,若是你的應用場景很在乎響應時延,那應該選擇使用 RocketMQ。
RocketMQ 的性能比 RabbitMQ 要高一個數量級,每秒鐘大概能處理幾十萬條消息。
RocketMQ 的劣勢是與周邊生態系統的集成和兼容程度不夠。
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 幾種常見的消息隊列,闡述了各類消息隊列的主要特色和優劣勢。
在瞭解了上面這些開源消息隊列各自的特色和優劣勢後,對於消息隊列及相關技術選型,相信你會有更深刻的理解和認識。如下幾條選擇的建議能夠參考:
每個消息隊列都有本身的優劣勢,須要根據現有系統的狀況,選擇最適合的消息隊列,更多細節和原理性的東西,還需在實踐中見真知!
參考