【轉】消息隊列的流派之爭

這篇文章的標題很難起,網上一翻全是各類MQ的性能比較,很容易讓人覺得我也是這麼「粗俗」的人(o(╯□╰)o)。我這篇文章想要表達的是—— 它們根本不是一個東西,有毛的性能比如較?  服務器

 

MQ是什麼

Message Queue(MQ),消息隊列中間件。不少人都說: MQ經過將消息的發送和接收分離來實現應用程序的異步和解偶 ,這個給人的直覺是——MQ是異步的,用來解耦的,可是這個只是MQ的效果而不是目的。MQ真正的目的是爲了 通信 ,屏蔽底層複雜的通信協議,定義了一套應用層的、更加簡單的通信協議。一個分佈式系統中兩個模塊之間通信要麼是HTTP,要麼是本身開發的TCP,可是這兩種協議其實都是原始的協議。HTTP協議很難實現兩端通信——模塊A能夠調用B,B也能夠主動調用A,若是要作到這個兩端都要背上WebServer,並且還不支持長鏈接(HTTP 2.0的庫根本找不到)。TCP就更加原始了,粘包、心跳、私有的協議,想想頭皮就發麻。MQ所要作的就是 在這些協議之上構建一個簡單的「協議」——生產者/消費者模型 。MQ帶給個人「協議」不是具體的通信協議,而是更高層次 通信模型 。它定義了兩個對象——發送數據的叫生產者;消費數據的叫消費者, 提供一個SDK讓咱們能夠定義本身的 生產者 和 消費者 實現消息通信而無視底層通信協議。架構

 

MQ的流派

列出功能表來比較MQ差別或者來一場「MQ性能大比武」的作法都是比較扯的,首先要作的事情應該是分類。我理解的MQ分爲兩個流派異步

 

有broker

這個流派一般有一臺服務器做爲Broker,全部的消息都經過它中轉。生產者把消息發送給它就結束本身的任務了,Broker則把消息主動推送給消費者(或者消費者主動輪詢)。分佈式

  • 重Topic流性能

    kafka、JMS就屬於這個流派,生產者會發送 key 和 數據 到Broker,由Broker比較key以後決定給那個消費者。這種模式是咱們最多見的模式,是咱們對MQ最多的印象。在這種模式下一個topic每每是一個比較大的概念,甚至一個系統中就可能只有一個topic,  topic某種意義上就是queue,生產者發送key至關於說:「hi,把數據放到 key 的隊列中」。大數據

   

如上圖所示,Broker定義了三個隊列,key1,key2,key3,生產者發送數據的時候會發送key1和data,Broker在推送數據的時候則推送data(也可能把key帶上)。    雖然架構同樣可是kafka的性能要比jms的性能不知道高到多少倍,因此基本這種類型的MQ只有kafka一種備選方案。若是你須要 一條暴力的數據流 (在意性能而非靈活性)那麼kafka是最好的選擇。spa

  • 輕Topic流設計

這種的表明是RabbitMQ(或者說是AMQP)。生產者發送 key 和 數據 ,消費者定義訂閱的 隊列 ,Broker收到數據以後會經過 必定的邏輯計算出key對應的隊列,而後把數據交給隊列 。code

   

注意到了嗎?這種模式下解耦了key和queue,在這種架構中queue是很是輕量級的(在RabbitMQ中它的上限取決於你的內存),消費者關心的只是本身的queue;生產者沒必要關心數據最終給誰只要指定key就好了,中間的那層映射在AMQP中叫exchange(交換機)。AMQP中有四種種exchange——Direct exchange:key就等於queue;Fanout exchange:無視key,給全部的queue都來一份;Topic exchange:key能夠用「寬字符」模糊匹配queue;最後一個厲害了Headers exchange:無視key,經過查看消息的頭部元數據來決定發給那個queue(AMQP頭部元數據很是豐富並且能夠自定義)。    這種結構的架構給通信帶來了很大的 靈活性 ,咱們能想到的通信方式均可以用這四種exchange表達出來。若是你須要一個 企業數據總線 (在意靈活性)那麼RabbitMQ絕對的值得一用。中間件

 

無broker

此門派是AMQP的「叛徒」,某位道友嫌棄AMQP太「重」(那是他沒看到用Erlang實現的時候是多麼的行雲流水) 因此設計了zeromq。這位道友很是睿智,他很是敏銳的意識到—— MQ是更高級的Socket,它是解決通信問題的。 因此ZeroMQ被設計成了一個「庫」而不是一箇中間件,這種實現也能夠達到——沒有broker的目的。

   

節點之間通信的消息都是發送到彼此的隊列中,每一個節點都既是 生產者又是消費者 。ZeroMQ作的事情就是封裝出一套相似於scoket的API能夠完成發送數據,讀取數據。    若是你仔細想一下其實ZeroMQ是這樣的

   

頓悟了嗎?Actor模型,ZeroMQ其實就是一個 跨語言的、重量級的Actor模型郵箱庫 。你能夠把本身的程序想象成一個actor,zeromq就是提供 郵箱 功能的庫;zeromq能夠實現同一臺機器的IPC通信也能夠實現不一樣機器的TCP、UDP通信。    若是你須要一個強大的、靈活、野蠻的通信能力,別猶豫zeromq。

 

MQ只能異步嗎

答案是否認了,首先ZeroMQ支持 請求->應答模式 ;其次RabbitMQ提供了 RPC 是地地道道的同步通信,只有JMS、kafka這種架構才只能作異步。咱們不少人第一次接觸MQ都是JMS之類的這種因此纔會產生這種 錯覺 。

 

總結

kafka,zeromq,rabbitmq表明了三種徹底不一樣風格的MQ架構;關注點徹底不一樣:

  • kafka在意的是性能,速度

  • rabbitmq追求的是靈活

  • zeromq追求的是輕量級、分佈式

若是你拿zeromq來作大數據量的傳輸功能,不是生產者的內存「爆掉」就是消費者被「壓死」;若是你用kafka作通信總線那絕對的不會快只能更慢;你想要rabbitmq實現分佈式,那真的是難爲它。

相關文章
相關標籤/搜索