當前使用較多的消息隊列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ等,而部分數據庫如Redis、MySQL以及phxsql也可實現消息隊列的功能。
RabbitMQ
RabbitMQ於2007年發布,是一個在AMQP(高級消息隊列協議)基礎上完成的,可復用的企業消息系統,是當前最主流的消息中間件之一。
主要特性
-
可靠性:提供了多種技術可以讓你在性能和可靠性之間進行權衡。這些技術包括持久性機制、投遞確認、發布者證實和高可用性機制
-
靈活的路由:消息在到達隊列前是通過交換機進行路由的。RabbitMQ為典型的路由邏輯提供了多種內置交換機類型。如果你有更復雜的路由需求,可以將這些交換機組合起來使用,你甚至可以實現自己的交換機類型,並且當做RabbitMQ的插件來使用
-
消息集群:在相同局域網中的多個RabbitMQ服務器可以聚合在一起,作為一個獨立的邏輯代理來使用
-
隊列高可用:隊列可以在集群中的機器上進行鏡像,以確保在硬件問題下還保證消息安全
-
支持多種協議:支持多種消息隊列協議
-
支持多種語言:用Erlang語言編寫,支持只要是你能想到的所有編程語言
-
管理界面:RabbitMQ有一個易用的用戶界面,使得用戶可以監控和管理消息Broker的許多方面
-
跟蹤機制:如果消息異常,RabbitMQ 提供消息跟蹤機制,使用者可以找出發生了什么
-
插件機制:提供了許多插件,來從多方面進行擴展,也可以編寫自己的插件。
優點
- 由於Erlang語言的特性,消息隊列性能較好,支持高並發
- 健壯、穩定、易用、跨平台、支持多種語言、文檔齊全
- 有消息確認機制和持久化機制,可靠性高
- 高度可定制的路由
- 管理界面較豐富,在互聯網公司也有較大規模的應用,社區活躍度高。
缺點
- 盡管結合 Erlang 語言本身的並發優勢,性能較好,但是不利於做二次開發和維護
- 實現了代理架構,意味着消息在發送到客戶端之前可以在中央節點上排隊。此特性使得RabbitMQ易於使用和部署,但是使得其運行速度較慢,因為中央節點 增加了延遲,消息封裝后也比較大需要學習比較復雜的接口和協議,學習和維護成本較高。
RocketMQ
RocketMQ出自阿里的開源產品,用Java語言實現,在設計時參考了Kafka,並做出了自己的一些改進,消息可靠性上比Kafka更好。RocketMQ在阿里內部被廣泛應用在訂單,交易,充值,流計算,消息推送,日志流式處理,binglog分發等場景。
主要特性
-
基於隊列模型:具有高性能、高可靠、高實時、分布式等特點
-
Producer、Consumer、隊列都支持分布式
-
Producer向一些隊列輪流發送消息,隊列集合稱為Topic。Consumer如果做廣播消費,則一個Consumer實例消費這個Topic對應的所有隊列如果做集群消費,則多個Consumer 實例平均消費這個Topic對應的隊列集合
-
能夠保證嚴格的消息順序
-
提供豐富的消息拉取模式
-
高效的訂閱者水平擴展能力
-
實時的消息訂閱機制
-
億級消息堆積 能力
-
較少的外部依賴。
優點
- 單機支持1萬以上持久化隊列
- RocketMQ的所有消息都是持久化的,先寫入系統PAGECACHE,然后刷盤,可以保證內存與磁盤都有一份數據,而訪問時,直接從內存讀取。
- 模型簡單,接口易用(JMS的接口很多場合並不太實用)
- 性能非常好,可以允許大量堆積消息在Broker中
- 支持多種消費模式,包括集群消費、廣播消費等
- 各個環節分布式擴展設計,支持主從和高可用
- 開發度較活躍,版本更新很快。
缺點
- 支持的客戶端語言不多,目前是Java及C++,其中C++還不成熟
- RocketMQ社區關注度及成熟度也不及前兩者
- 沒有在MQ核心里實現JMS等接口
ActiveMQ
ActiveMQ是由Apache出品,ActiveMQ是一個完全支持JMS1.1和J2EE 1.4規范的JMS Provider實現。它非常快速,支持多種語言的客戶端和協議,而且可以非常容易的嵌入到企業的應用環境中,並有許多高級功能。
主要特性
-
服從JMS規范:JMS 規范提供了良好的標准和保證,包括:同步 或 異步 的消息分發,一次和僅一次的消息分發,消息接收和訂閱等等。遵從JMS規范的好處在於,不論使用什么JMS實現提供者,這些基礎特性都是可用的
-
連接靈活性:ActiveMQ提供了廣泛的連接協議,支持的協議有:HTTP/S,IP多播,SSL,TCP,UDP等等。對眾多協議的支持讓ActiveMQ擁有了很好的靈活性
-
支持的協議種類多:OpenWire、STOMP、REST、XMPP、AMQP
-
持久化插件和安全插件:ActiveMQ提供了多種持久化選擇。而且,ActiveMQ的安全性也可以完全依據用戶需求進行自定義鑒權和授權
-
支持的客戶端語言種類多:除了Java之外,還有:C/C++,.NET,Perl,PHP,Python,Ruby
-
代理集群:多個ActiveMQ代理可以組成一個集群來提供服務
-
異常簡單的管理:ActiveMQ是以開發者思維被設計的。所以,它並不需要專門的管理員,因為它提供了簡單又使用的管理特性。有很多中方法可以監控ActiveMQ不同層面的數據,包括使用在JConsole或者在ActiveMQ的WebConsole中使用JMX。通過處理JMX的告警消息,通過使用命令行腳本,甚至可以通過監控各種類型的日志。
優點
- 跨平台(JAVA編寫與平台無關,ActiveMQ幾乎可以運行在任何的JVM上)
- 可以用JDBC:可以將數據持久化到數據庫。雖然使用JDBC會降低ActiveMQ的性能,但是數據庫一直都是開發人員最熟悉的存儲介質
- 支持JMS規范:支持JMS規范提供的統一接口;
- 支持自動重連和錯誤重試機制
- 有安全機制:支持基於shiro,jaas等多種安全配置機制,可以對Queue/Topic進行認證和授權
- 監控完善:擁有完善的監控,包括WebConsole,JMX,Shell命令行,Jolokia的RESTful API
- 界面友善:提供的WebConsole可以滿足大部分情況,還有很多第三方的組件可以使用,比如hawtio
缺點
- 社區活躍度不及RabbitMQ高
- 根據其他用戶反饋,會出莫名其妙的問題,會丟失消息
- 目前重心放到activemq6.0產品Apollo,對5.x的維護較少
- 不適合用於上千個隊列的應用場景
kafka
Apache Kafka是一個分布式消息發布訂閱系統。它最初由LinkedIn公司基於獨特的設計實現為一個分布式的日志提交系統(a distributed commit log),之后成為Apache項目的一部分。Kafka性能高效、可擴展良好並且可持久化。它的分區特性,可復制和可容錯都是其不錯的特性。
主要特性
-
快速持久化:可以在O(1)的系統開銷下進行消息持久化
-
高吞吐:在一台普通的服務器上既可以達到10W/s的吞吐速率
-
完全的分布式系統:Broker、Producer和Consumer都原生自動支持分布式,自動實現負載均衡
-
支持同步和異步復制兩種高可用機制
-
支持數據批量發送和拉取
-
零拷貝技術(zero-copy):減少IO操作步驟,提高系統吞吐量
-
數據遷移、擴容對用戶透明
-
無需停機即可擴展機器
-
其他特性:豐富的消息拉取模型、高效訂閱者水平擴展、實時的消息訂閱、億級的消息堆積能力、定期刪除機制
優點
- 客戶端語言豐富:支持Java、.Net、PHP、Ruby、Python、Go等多種語言
- 高性能:單機寫入TPS約在100萬條/秒,消息大小10個字節
- 提供完全分布式架構,並有replica機制,擁有較高的可用性和可靠性,理論上支持消息無限堆積
- 支持批量操作
- 消費者采用Pull方式獲取消息。消息有序,通過控制能夠保證所有消息被消費且僅被消費一次
- 有優秀的第三方KafkaWeb管理界面Kafka-Manager
- 在日志領域比較成熟,被多家公司和多個開源項目使用。
缺點
- Kafka單機超過64個隊列/分區時,Load時會發生明顯的飆高現象。隊列越多,負載越高,發送消息響應時間變長
- 使用短輪詢方式,實時性取決於輪詢間隔時間
- 消費失敗不支持重試
- 支持消息順序,但是一台代理宕機后,就會產生消息亂序
- 社區更新較慢。
常見消息中間就對比分析圖
從公司基礎建設力量角度
-
中小型軟件公司,建議選RabbitMQ,一方面,erlang語言天生具備高並發的特性,而且他的管理界面用起來十分方便。他的弊端也在這里,雖然RabbitMQ是開源的,然而國內有幾個能定制化開發erlang的程序員呢?所幸,RabbitMQ的社區十分活躍,可以解決開發過程中遇到的bug,這點對於中小型公司來說十分重要。不考慮RocketMQ和kafka的原因是,一方面中小型軟件公司不如互聯網公司,數據量沒那么大,選消息中間件,應首選功能比較完備的,所以kafka排除。不考慮RocketMQ的原因是,RocketMQ是阿里出品,如果阿里放棄維護RocketMQ,中小型公司一般抽不出人來進行RocketMQ的定制化開發,因此不推薦。
-
大型軟件公司,根據具體使用在RocketMQ和kafka之間二選一。一方面,大型軟件公司,具備足夠的資金搭建分布式環境,也具備足夠大的數據量。針對RocketMQ,大型軟件公司也可以抽出人手對RocketMQ進行定制化開發,畢竟國內有能力改JAVA源碼的人,還是相當多的。至於kafka,根據業務場景選擇,如果有日志采集功能,肯定是首選kafka了。
從業務場景角度出發
-
RocketMQ定位於非日志的可靠消息傳輸(日志場景也OK),目前RocketMQ在阿里集團被廣泛應用在訂單,交易,充值,流計算,消息推送,日志流式處理,binglog分發等場景。
-
Kafka是LinkedIn開源的分布式發布-訂閱消息系統,目前歸屬於Apache定級項目。Kafka主要特點是基於Pull的模式來處理消息消費,追求高吞吐量,一開始的目的就是用於日志收集和傳輸。0.8版本開始支持復制,不支持事務,對消