這篇文章的標題很難起,網上一翻全是各種mq的效能比較,很容易讓人以為我也是這麼「粗俗」的人。我這篇文章想要表達的是——它們根本不是乙個東西,有毛的效能好比較?
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則把訊息主動推送給消費者(或者消費者主動輪詢)。
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是最好的選擇。
這種的代表是rabbitmq(或者說是amqp)。生產者傳送key和資料,消費者定義訂閱的佇列,broker收到資料之後會通過一定的邏輯計算出key對應的佇列,然後把資料交給佇列。
注意到了嗎?這種模式下解耦了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架構;關注點完全不同:
如果你拿zeromq來做大資料量的傳輸功能,不是生產者的記憶體「爆掉」就是消費者被「壓死」;如果你用kafka做通訊匯流排那絕對的不會快只能更慢;你想要rabbitmq實現分布式,那真的是難為它。
訊息佇列的流派之爭
message queue mq 訊息佇列中介軟體。很多人都說 mq通過將訊息的傳送和接收分離來實現應用程式的非同步和解偶,這個給人的直覺是 mq是非同步的,用來解耦的,但是這個只是mq的效果而不是目的。mq真正的目的是為了通訊,遮蔽底層複雜的通訊協議,定義了一套應用層的 更加簡單的通訊協議。乙個分...
訊息佇列的流派之爭
message queue mq 訊息佇列中介軟體。很多人都說 mq通過將訊息的傳送和接收分離來實現應用程式的非同步和解偶,這個給人的直覺是 mq是非同步的,用來解耦的,但是這個只是mq的效果而不是目的。mq真正的目的是為了通訊,遮蔽底層複雜的通訊協議,定義了一套應用層的 更加簡單的通訊協議。乙個分...
訊息佇列的流派
什麼是 mq message queue mq 訊息佇列中介軟體。很多人都說 mq 通過將訊息的傳送和接收分離來實現應用程式的非同步和解偶,這個給人的直覺是 mq 是非同步的,用來解耦的,但是這個只是 mq 的效果而不是目的。mq 真正的目的是為了通訊,遮蔽底層複雜的通訊協議,定義了一套應用層的 更...