什麼是 mq
message queue(mq),訊息佇列中介軟體。很多人都說:mq 通過將訊息的傳送和接收分離來實現應用程式的非同步和解偶,這個給人的直覺是——mq 是非同步的,用來解耦的,但是這個只是 mq 的效果而不是目的。mq 真正的目的是為了通訊,遮蔽底層複雜的通訊協議,定義了一套應用層的、更加簡單的通訊協議。乙個分布式系統中兩個模組之間通訊要麼是 http,要麼是自己開發的 tcp,但是這兩種協議其實都是原始的協議。http 協議很難實現兩端通訊——模組 a 可以呼叫 b,b 也可以主動呼叫 a,如果要做到這個兩端都要背上 webserver,而且還不支援長連線(http 2.0 的庫根本找不到)。tcp 就更加原始了,粘包、心跳、私有的協議,想一想頭皮就發麻。mq 所要做的就是在這些協議之上構建乙個簡單的「協議」——生產者/消費者模型。mq 帶給我的「協議」不是具體的通訊協議,而是更高層次通訊模型。它定義了兩個物件——傳送資料的叫生產者;接收資料的叫消費者, 提供乙個 sdk 讓我們可以定義自己的生產者和消費者實現訊息通訊而無視底層通訊協議
這個流派通常有一台伺服器作為 broker,所有的訊息都通過它中轉。生產者把訊息傳送給它就結束自己的任務了,broker 則把訊息主動推送給消費者(或者消費者主動輪詢)
kafka、jms(activemq)就屬於這個流派,生產者會傳送 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 的 mq 的代表是 zeromq。該作者非常睿智,他非常敏銳的意識到——mq 是更高階的 socket,它是解決通訊問題的。所以 zeromq 被設計成了乙個「庫」而不是乙個中介軟體,這種實現也可以達到——沒有 broker 的目的
節點之間通訊的訊息都是傳送到彼此的佇列中,每個節點都既是生產者又是消費者。zeromq 做的事情就是封裝出一套類似於 socket 的 api 可以完成傳送資料,讀取資料
zeromq 其實就是乙個跨語言的、重量級的 actor 模型郵箱庫。你可以把自己的程式想象成乙個 actor,zeromq 就是提供郵箱功能的庫;zeromq 可以實現同一臺機器的 rpc 通訊也可以實現不同機器的 tcp、udp 通訊,如果你需要乙個強大的、靈活、野蠻的通訊能力,別猶豫 zeromq
queue: 乙個發布者發布訊息,下面的接收者按佇列順序接收,比如發布了 10 個訊息,兩個接收者 a,b 那就是 a,b 總共 會收到 10 條訊息,不重複。
topic: 乙個發布者發布訊息,有兩個接收者 a,b 來訂閱,那麼發布了 10 條訊息,a,b 各收到 10 條訊息。
型別 topic queue
概要 publish subscribe messaging 發布訂閱訊息 point-to-point 點對點
有無狀態 topic 資料預設不落地,是無狀態的。 queue 資料缺省會在 mq 伺服器上以檔案形式儲存,比如 activemq 一般儲存在 $amq_home\data\kr-store\data 下面。也可以配置成 db 儲存。
完整性保障 並不保證 publisher 發布的每條資料,subscriber 都能接受到。 queue 保證每條資料都能被 receiver 接收。
訊息是否會丟失 一般來說 publisher 發布訊息到某乙個 topic 時,只有正在監聽該 topic 位址的 sub 能夠接收到訊息;如果沒有 sub 在監聽,該 topic 就丟失了。 sender 傳送訊息到目標 queue,receiver 可以非同步接收這個 queue 上的訊息。queue 上的訊息如果暫時沒有 receiver 來取,也不會丟失。
訊息發布接收策略 一對多的訊息發布接收策略,監聽同乙個 topic 位址的多個 sub 都能收到 publisher 傳送的訊息。sub 接收完通知 mq 伺服器 一對一的訊息發布接收策略,乙個 sender 傳送的訊息,只能有乙個 receiver 接收。receiver 接收完後,通知 mq 伺服器已接收,mq 伺服器對 queue 裡的訊息採取刪除或其他操作。
訊息佇列的流派之爭
message queue mq 訊息佇列中介軟體。很多人都說 mq通過將訊息的傳送和接收分離來實現應用程式的非同步和解偶,這個給人的直覺是 mq是非同步的,用來解耦的,但是這個只是mq的效果而不是目的。mq真正的目的是為了通訊,遮蔽底層複雜的通訊協議,定義了一套應用層的 更加簡單的通訊協議。乙個分...
訊息佇列的流派之爭
message queue mq 訊息佇列中介軟體。很多人都說 mq通過將訊息的傳送和接收分離來實現應用程式的非同步和解偶,這個給人的直覺是 mq是非同步的,用來解耦的,但是這個只是mq的效果而不是目的。mq真正的目的是為了通訊,遮蔽底層複雜的通訊協議,定義了一套應用層的 更加簡單的通訊協議。乙個分...
大話訊息佇列的流派之爭
這篇文章的標題很難起,網上一翻全是各種mq的效能比較,很容易讓人以為我也是這麼 粗俗 的人。我這篇文章想要表達的是 它們根本不是乙個東西,有毛的效能好比較?mq是什麼?message queue mq 訊息佇列中介軟體。很多人都說 mq通過將訊息的傳送和接收分離來實現應用程式的非同步和解偶,這個給人...