rocketmq订阅多个主题_RocketMQ 的消息模型
攝影: 雙兒
開篇
不知道大家跟我是不是有同樣的困惑, 在學習不同的消息框架時都會接觸到主題, 隊列, 分區, 生產者, 消費者等等一些概念. ?有時會覺得很抽象, 他們之間到底是如何配合工作, 完成消息的發送和消費的過程的.
今天我們就通過學習消費模型來了解下這些概念. 從而搞清楚他們到底是如何工作的.
消息模型
現在流行的有兩種消息模型: 隊列模型和發布-訂閱模型, 二者之間有什么關系呢? 相信大家能夠猜到, 發布-訂閱模型是從隊列模型演進而來, 為什么會這樣演進, 解決了什么問題呢? 接下來讓我們一起學習一下.
隊列模型
隊列模型顧名思義, 就是根據隊列這種數據結構來設計的, 結構如下圖所示:?
生產者發送消息到消費隊列的尾部, ?消費者從消費隊列前獲取消息進行消費. ?隊列模型很簡單, 但是這個結構有一個問題就是, 當有多個消費者的時候, 他們之間是競爭關系, 也就意味著每個消費者只能消費到部分消息, 并不是全量消息.
有人會說,我們可以有多個對立呀, 讓生產者寫多個隊列, 每個消費者消費一個隊列. 這種方案可以解決問題, 但是很浪費資源呀. 如果消費者多了, 我得重復多少份消息呀. 為了解決這個問題, 演化出了發布-訂閱模型.
發布-訂閱模型
發布訂閱模型的結構如下圖所示:
在發布 - 訂閱模型中,消息的發送方稱為發布者(Publisher),消息的接收方稱為訂閱者(Subscriber),服務端存放消息的容器稱為主題(Topic)。發布者將消息發送到主題中,訂閱者在接收消息之前需要先“訂閱主題”。“訂閱”在這里既是一個動作,同時還可以認為是主題在消費時的一個邏輯副本,每份訂閱中,訂閱者都可以接收到主題的所有消息。
在發布 - 訂閱模型中,消息的發送方稱為發布者(Publisher),消息的接收方稱為訂閱者(Subscriber),服務端存放消息的容器稱為主題(Topic)。發布者將消息發送到主題中,訂閱者在接收消息之前需要先“訂閱主題”。“訂閱”在這里既是一個動作,同時還可以認為是主題在消費時的一個邏輯副本,每份訂閱中,訂閱者都可以接收到主題的所有消息。
這里我們可以發現, 隊列模型和發布-訂閱模型最大的區別就是,一份消息數據能不能被消費多次的問題。
RocketMQ的消息模型
學習了兩種消息模型之后, 讓我們來學習一下RocketMQ的消息模型. 為了便于后面的講解, 我先把RocketMQ消息模型的結構圖放在下面. ?這是一個標準的發布-訂閱模型. 但是不知道大家發現沒有, 除了上文我們介紹的發布-訂閱模型中的生成者, 消費者, 主題的概念之外. RocketMQ的消息模型中又多了一個隊列的概念. 這個隊列是干什么的呢? 為什么需要一個隊列, 他和主題又有什么關系呢??
別著急, 我們一點點來分析, 要解答這個問題, 我們需要從消息隊列的消費機制----請求-確認機制開始說起
請求-確認機制
請求-確認機制主要是用來保證消息不會丟失. 對于生產者來說,將消息發送給Broker, Broker在收到消息并將消息寫入主題或者隊列中后,會給生產者發送確認響應。如果生產者沒有收到確認或者收到失敗的響應,則會重新發送消息。對于消費者來說,在收到消息并完成自己的消費業務邏輯后,也會給服務端發送消費成功的確認。
引入請求-確認機制之后,消費端在消費消息時就會收到限制,為了確保消息的有序性,在某一條消息被成功消費之前,下一條消息是不能被消費的,否則就會破壞有序性。這就決定了一個主題同時只能有一個消費者在進行消費。這對于一個偉大的中間件來說怎么可能呢, 不能并行消費是絕對不能容忍的, 于是RocketMQ在主題的基礎上又引入了隊列的概念,每個主題下面可以包含多個隊列, 通過多隊列來實現多實例并行生產和消費。RocketMQ的消息模型大致如下圖所示:
圖中的主題(Topic),隊列(Queue), 消費者(Consumer),生產者(Producer)大家都已經熟悉了, 但是圖中的消費組(Consumer Group)和生產組(Producer Group)又是什么呢?
RocketMQ中,消費組相當于訂閱者,訂閱 Topic 是以一個消費組來訂閱的,發送到 Topic 的消息,只會被訂閱此 Topic 的每個 group 中的一個 consumer 消費。 一個消費組中可以包含多個消費者, 不同的消費組之間是互相不受影響的,也就是說一條消息,消費組1 消費過了, 也會被消費組2消費。也就是說, 一個 隊列(Queue),只能被消費組里的一個消費者消費,但是可以同時被多個消費組消費,消費組里的每個消費者是關聯到一個 Queue的,因此有這樣的說法:對于一個 topic,同一個 group 中的消費者個數和隊列個數最好一致, 這樣能得到充分的使用, 也不會浪費資源.
既然多個消費組都可以消費同一條消息. 那你可能會好奇我們有怎么記住每一個消費組消費到哪條消息了呢?首先為了保證消息被多個消費組消費,一個消費組消費完消息后一定不會刪除,在RocketMQ中使用的是消費位置(offset)記錄每個消費組在每個隊列上消費到哪一條消息。每消費一條消息消費位置就會加1. ?當所有訂閱該該主題的所有消費者組都消費了這條消息以后, 才能刪除這條消息。
生產組則是發布者, 一個生產組中可以有多個生產者。生產者在生產消息時可以在采用隨機, 輪詢, 哈希等方式向任何隊列發送消息。
好了, RocketMQ的消息模型我們就介紹到這里了, 順著這個消息模型, 大家是不是也產生了很多的疑問呢?引入了并行消費的方案,如何保證消息的有序性呢?除了請求-確認機制保證消息的可靠性之外還有什么機制呢?
如果消費者消費的太慢, 導致消息積壓要怎么處理呢?
總結
以上是生活随笔為你收集整理的rocketmq订阅多个主题_RocketMQ 的消息模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 容量法和库仑法的异同点_快速搞懂「活性污
- 下一篇: 中报表导出带表头_来看看Java是 如何