1. 程式人生 > >訊息佇列的技術選擇分析

訊息佇列的技術選擇分析

原文地址:http://blog.fity.cn/post/377/
2016-02

訊息中介軟體是一種由訊息傳送機制或訊息佇列模式組成的中介軟體技術,利用高效可靠的訊息傳遞機制進行平臺無關的資料交流,並基於資料通訊來進行分散式系統的整合。目前業界有很多的MQ產品,像RabbitMQ、ActiveMQ、ZeroMQ等都是極好的訊息中介軟體,但是我們在專案中該選擇哪個更適合呢?本文針對以下幾種訊息佇列產品作了評估比較:RabbitMQ、ZeroMQ、ActiveMQ、MSMQ、Redis、memcacheQ

題外話:這裡我們可以先思考個小問題“Web應用中為什麼會需要訊息佇列服務?”

在高併發環境下,由於來不及同步處理,請求往往會發生堵塞(主要原因),比如說,大量的insert,update之類的請求同時到達mysql,直接導致無數的行鎖表鎖,甚至最後請求會堆積過多,從而觸發too many connections錯誤。通過使用訊息佇列,我們可以非同步處理請求,從而緩解系統的壓力。


RabbitMQ
是使用Erlang編寫的一個開源的訊息佇列,本身支援很多的協議:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它變的非常重量級,更適合於企業級的開發。是AMQP協議領先的一個實現,它實現了代理(Broker)架構,意味著訊息在傳送到客戶端之前可以在中央節點上排隊。對路由(Routing),負載均衡(Load balance)或者資料持久化都有很好的支援。此特性使得RabbitMQ易於使用和部署,適宜於很多場景如路由、負載均衡或訊息持久化等,用訊息佇列只需幾行程式碼即可搞定。但是,這使得它的可擴充套件性差,速度較慢,因為中央節點增加了延遲,訊息封裝後也比較大。如需配置RabbitMQ則需要在目標機器上安裝Erlang環境。

點選在新視窗中瀏覽此圖片


?MQ(ZeroMQ)
號稱最快的訊息佇列系統,尤其針對大吞吐量的需求場景。是一個非常輕量級的訊息系統,專門為高吞吐量/低延遲的場景開發,在金融界的應用中經常可以發現它。與RabbitMQ相比,ZeroMQ支援許多高階訊息場景,但是你必須實現ZeroMQ框架中的各個塊(比如Socket或Device等)。

?MQ(ZeroMQ)能夠實現RabbitMQ不擅長的高階/複雜的佇列,但是開發人員需要自己組合多種技術框架,技術上的複雜度是對這MQ能夠應用成功的挑戰。ZeroMQ具有一個獨特的非中介軟體的模式,你不需要安裝和執行一個訊息伺服器或中介軟體,因為你的應用程式將扮演了這個服務角色。你只需要簡單的引用ZeroMQ程式庫,可以使用NuGet安裝,然後你就可以愉快的在應用程式之間傳送訊息了。但是ZeroMQ僅提供非永續性的佇列,也就是說如果down機,資料將會丟失。其中,Twitter的Storm中使用ZeroMQ作為資料流的傳輸。ZeroMQ非常靈活,但是你必須學習它的80頁的手冊(如果你要寫一個分散式系統,一定要閱讀它)。


ZeroMQ沒有中介軟體架構,不需要任何服務程序和執行。事實上,你的應用程式端點扮演了這個服務角色。這讓部署起來非常簡單,但擔心的是,你沒有地方可以觀察它是否有問題出現。就目前瞭解到的,ZeroMQ僅提供非永續性的佇列。你可以在需要的地方實現自己的審計和資料恢復功能。

點選在新視窗中瀏覽此圖片


MSMQ
這是微軟的產品裡唯一被認為有價值的東西。如果MSMQ能證明可以應對這種任務,他們將選擇使用它。關鍵是這個東西並不複雜,除了接收和傳送,沒有別的;它有一些硬性限制,比如最大訊息體積是4MB。然而,通過和一些像MassTransit 或 NServiceBus這樣的軟體的連線,它完全可以解決這些問題。

點選在新視窗中瀏覽此圖片


Jafka/Kafka
kafka(能將訊息分散到不同的節點上)是LinkedIn於2010年12月開發並開源的一個分散式MQ系統,現在是Apache的一個孵化專案,是一個高效能跨語言分散式Publish/Subscribe訊息佇列系統,而Jafka是在Kafka之上孵化而來的,即Kafka的一個升級版。具有以下特性:快速持久化,可以在O(1)的系統開銷下進行訊息持久化;高吞吐,在一臺普通的伺服器上既可以達到10W/s的吞吐速率;完全的分散式系統,Broker、Producer、Consumer都原生自動支援分散式,自動實現複雜均衡;支援Hadoop資料並行載入,對於像Hadoop的一樣的日誌資料和離線分析系統,但又要求實時處理的限制,這是一個可行的解決方案。Kafka通過Hadoop的並行載入機制來統一了線上和離線的訊息處理,這一點也是本課題所研究系統所看重的。Apache Kafka相對於ActiveMQ是一個非常輕量級的訊息系統,除了效能非常好之外,還是一個工作良好的分散式系統。

點選在新視窗中瀏覽此圖片


Apache ActiveMQ
ActiveMQ居於兩者(RabbitMQ & ZeroMQ)之間,類似於ZemoMQ,它可以部署於代理模式和P2P模式。類似於RabbitMQ,它易於實現高階場景,而且只需付出低消耗。
ActiveMQ被譽為Java世界的中堅力量。它有很長的歷史,而且被廣泛的使用。它還是跨平臺的,給那些非微軟平臺的產品提供了一個天然的整合接入點。然而,它只有跑過了MSMQ才有可能被考慮。如需配置ActiveMQ則需要在目標機器上安裝Java環境。

點選在新視窗中瀏覽此圖片

需要注意一點的是ActiveMQ的下一代產品為Apollo,Apollo以ActiveMQ原型為基礎,是一個更快、更可靠、更易於維護的訊息代理工具。Apache稱Apollo為最快、最強健的STOMP(Streaming Text Orientated Message Protocol,流文字定向訊息協議)伺服器。 
Apollo的特性如下:
支援Stomp 1.0和Stomp 1.1協議
主題和佇列
佇列瀏覽器
主題持久訂閱
映象佇列
可靠的訊息傳遞
訊息過期和交換
訊息選擇器
JAAS驗證
基於ACL的授權
支援SSL/TLS,證書驗證
REST Management API

點選在新視窗中瀏覽此圖片


Redis
是一個Key-Value的NoSQL資料庫,開發維護很活躍,雖然它是一個Key-Value資料庫儲存系統,但它本身支援MQ功能,所以完全可以當做一個輕量級的佇列服務來使用。對於RabbitMQ和Redis的入隊和出隊操作,各執行100萬次,每10萬次記錄一次執行時間。測試資料分為128Bytes、512Bytes、1K和10K四個不同大小的資料。實驗表明:入隊時,當資料比較小時Redis的效能要高於RabbitMQ,而如果資料大小超過了10K,Redis則慢的無法忍受;出隊時,無論資料大小,Redis都表現出非常好的效能,而RabbitMQ的出隊效能則遠低於Redis。

MemcacheQ
持久化訊息佇列memcacheq(簡稱mcq)是一個輕量級的訊息佇列,MemcacheQ的特性:
1 簡單易用
2 處理速度快
3 多條佇列
4 併發效能好
5 與memcache的協議相容。這就意味著只要裝了memcache的extension就可以了,不需要額外的外掛。
6 在zend framework中使用也很方便。

最終,這幾個產品:
1. 都有各自客戶端API或支援多種程式語言;
2. 都有大量的文件;
3. 都提供了積極的支援。
4. ActiveMQ、RabbitMQ、MSMQ、Redis都需要啟動服務程序,這些都可以監控和配置,其他幾個就有問題了
5. 都相對提供了良好的可靠性(一致性)、擴充套件性和負載均衡,當然還有效能

這裡就不瞎扯了,下面附上一組從網上擷取的測試結果。顯示的是傳送和接受的每秒鐘的訊息數。整個過程共產生1百萬條1K的訊息。測試的執行是在一個Windows Vista單機上進行的。

點選在新視窗中瀏覽此圖片

就像你看到的,ZeroMQ和其它的不是一個級別。它的效能驚人的高。儘管這樣,但這個產品不提供訊息持久化、無法方便儲存及監控中間過程,需要自己實現審計和資料恢復,因此在易用性和HA上不是令人滿意。結論很清楚:如果你希望一個應用程式傳送訊息越快越好,你選擇ZeroMQ。當你不太在意偶然會丟失某些訊息的情況下更有價值。

本文博主未來往事更希望(也不是很希望很希望)選擇使用的是Rabbit,Rabbitmq內建了ha,如果組建cluster,負載均衡之類的問題就無需擔憂了同時可以設定佇列映象。但這種事情是應該做更多的測試,你最終會有一個最愛,我所聽到的、讀到的各種關於Rabbit的事情讓我覺得它應該是最佳選擇。
推薦閱讀

其他一些佇列列表,這裡就不再一一分析,如果需要了解更多可自行google。
If you can do a better test result -just comment it here so I could update this post. Thanks.