MQ 訊息佇列的概覽

2021-10-02 04:58:53 字數 2775 閱讀 6160

目錄

前言:1. rocketmq對比kafka?rocketmq怎麼做到低延遲?

2. 主題和佇列有什麼區別?

3. 例外的訊息模型-rabbitmq(依然再用佇列的思想)

4. rocketmq的訊息模型

5. kafka模型

6. 總結

好的架構不是設計出來的,而是演進出來的。

這個話很重要,也很有啟發。

業務最適合的是最好的架構。

kafka中到處都是「批量和非同步」設計,它更關注的是整體的吞吐量,而rocketmq的設計選擇更多的是盡量及時處理請求。

比如發訊息,同樣是使用者呼叫了send()方法,rockmq它會直接把這個訊息發出去,而kafka會把這個訊息放到本地快取裡面,然後擇機非同步批量傳送。

所以,rocketmq它的時延更小一些,而kafka的吞吐量更高。

在維基百科中,佇列的定義是這樣的:

佇列是先進先出(fifo, first-in-first-out)的線性表(linear list)。在具體應用中通常用鍊錶或者陣列來實現。佇列只允許在後端(稱為 rear)進行插入操作,在前端(稱為 front)進行刪除操作。

出隊嚴格有序,沒有讀的操作,讀就是出隊,從佇列中刪除。

早期的訊息佇列就是按照這種資料結構設計的。

如果這樣設計,那麼生產者會按照順序塞到佇列裡面,而訊息也只能唄其中乙個消費者收到。

但是如果想讓所有的消費者都能收到全量的訊息,總不能每乙個都建立乙個佇列吧?

但是乙個訊息資料被複製到多個佇列浪費了資源,而且,違背了訊息佇列解耦的設計初衷。

所以出現了發布訂閱模型

綜上,發布者發布主題,可以有多個訂閱者訂閱這個主題。然後訂閱者可以接收到訊息。

訊息的傳送方稱為發布者(publisher)

訊息的接收方稱為訂閱者(subscriber)

服務端存放訊息的容器稱為主題(topic)

這兩種模型區別就是,生產者就是發布者,消費者就是訂閱者,佇列就是主題,並沒有本質的區別。它們最大的區別其實就是,乙份訊息資料能不能被消費多次的問題。

這就是生產者與消費者 與 發布訂閱模式的區別。

發布 - 訂閱模型在功能層面上是可以相容佇列模型的。

現在大部分的訊息佇列都是發布訂閱模式。

rabbitmq還在用佇列模型。怎麼解決多個消費者的問題嗎?

因為rabbitmq有著自己獨有的exchange模組。

因為生產者直接把訊息傳送給exchange模組,然後呢 exchange模組來決定訊息投遞到那些佇列中。

由exchange上面配置的策略來決定將訊息投遞到那些佇列裡面。

同乙份訊息如果需要被多個消費者來消費,需要配置 exchange 將訊息傳送到多個佇列,每個佇列中都存放乙份完整的訊息資料,可以為乙個消費者提供消費服務。這也可以變相地實現新發布 - 訂閱模型中,「乙份訊息資料可以被多個訂閱者來多次消費」這樣的功能。

還是通過佇列實現,有著多個副本相當於,但是聰明的一點在於有乙個exchange模組,大概~

官網相關部分:

幾乎所有的訊息佇列產品都使用一種非常樸素的「請求 - 確認」機制,確保訊息不會在傳遞過程中由於網路或伺服器故障丟失。

在生產端,生產者先將訊息傳送給服務端,也就是 broker,服務端在收到訊息並將訊息寫入主題或者佇列中後,會給生產者傳送確認的響應。

如果生產者沒有收到服務端的確認或者收到失敗的響應,則會重新傳送訊息;(重試機制)

在消費端,消費者在收到訊息並完成自己的消費業務邏輯(比如,將資料儲存到資料庫中)後,也會給服務端傳送消費成功的確認,服務端只有收到消費確認後,才認為一條訊息被成功消費,否則它會給消費者重新傳送這條訊息,直到收到對應的消費成功確認。(消費者也必須需要給生產者乙個明確的確認訊息)

但是!!!為了確保訊息的有序性,在某一條訊息被成功消費之前,下一條訊息是不能被消費的,否則就會出現訊息空洞,違背了有序性這個原則。

為了解決這個問題,rocketmq 在主題下面增加了佇列的概念。

每個主題包含多個佇列,通過多個佇列來實現多例項並行生產和消費。需要注意的是,rocketmq 只在佇列上保證訊息的有序性,主題層面是無法保證訊息的嚴格順序的。

rocketmq 中,訂閱者的概念是通過消費組(consumer group)來體現的。

也就是說,一條訊息被 consumer group1 消費過,也會再給 consumer group2 消費。

消費組中包含多個消費者,同乙個組內的消費者是競爭消費的關係,每個消費者負責消費組內的一部分訊息。如果一條訊息被消費者 consumer1 消費了,那同組的其他消費者就不會再收到這條訊息。(因為是競爭關係)

和rocketmq很類似。唯一的區別是,在 kafka 中,佇列這個概念的名稱不一樣,kafka 中對應的名稱是「分割槽(partition)」,含義和功能是沒有任何區別的。

所以通過分割槽來進行(但是!!!為了確保訊息的有序性,在某一條訊息被成功消費之前,下一條訊息是不能被消費的,否則就會出現訊息空洞,違背了有序性這個原則。)滿足這個事的分割槽。

像 kafka 和 rocketmq 的業務模型基本是一樣的,並不是說他們的實現就是一樣的,實際上這兩個訊息佇列的實現是完全不同的。

接下來還要深入學習裡面的實現和設計模式。

訊息佇列MQ

目錄 一 簡介 二 為什麼需要訊息佇列 mq 三 介紹 訊息佇列 message queuing 在電腦科學中,是一種程序間通訊或同一程序間不同執行緒的通訊方式。廣義上講訊息佇列是解決分布式系統中,各個功能模組間的資訊傳遞通訊方式。與檔案傳輸和rpc相比,訊息佇列具有更好的平台無關性,並能夠很好地支...

MQ訊息佇列

1.解耦 系統a將userid寫到訊息佇列中,系統c和系統d從訊息佇列中拿資料。這樣有什麼好處?系統a只負責把資料寫到佇列中,誰想要或不想要這個資料 訊息 系統a一點都不關心。即便現在系統d不想要userid這個資料了,系統b又突然想要userid這個資料了,都跟系統a無關,系統a一點 都不用改。系...

MQ訊息佇列應用

很榮幸,原來一直聽說的訊息佇列終於在前段時間用到了自己的專案中。為什麼會用到訊息佇列?毫無疑問,當然是傳輸訊息。這裡訊息一般是一串字串,當然,訊息的含義很多,可以是 hello world 可以是 你吃飯了嗎?可以是一串正式的xml報文。也可以是乙個txt檔案或者xml檔案 在用active mq的...