MQ 系列:消息中間件執行原理
1 關於消息中間件
1.1 什麼是消息中間件?
消息中間件是指在分佈式系統中完成消息的發送和接收的基礎軟件。
消息中間件也可以稱消息隊列(Message Queue / MQ),用高效可靠的消息傳遞機制進行與平臺無關的數據交流,並基於數據通信來進行分佈式系統的集成。通過提供消息傳遞和消息隊列模型,可以在分佈式環境下擴展進程的通信。
簡而言之,互聯網場景中經常使用消息中間件進行消息路由、訂閱發佈、異步處理等操作,來緩解系統的壓力。
1.2 它解決了我們哪些痛點?
1、解耦: 比如說系統 A 會交給系統 B 去處理一些事情,但是 A 不想直接跟 B 有關聯,避免耦合太強,就可以通過在 A,B 中間加入消息隊列,A 將要任務的事情交給消息隊列 ,B 訂閱消息隊列來執行任務。
這種場景很常見,比如 A 是訂單系統,B 是庫存系統,可以通過消息隊列把削減庫存的工作交予 B 系統去處理。如果 A 系統同時想讓 B、C、D... 多個系統處理問題的時候,這種優勢就更加明顯了。
2、有序性: 先進先出原理,先來先處理,比如一個系統處理某件事需要很長一段時間,但是在處理這件事情時候,有其他人也發出了請求,可以把請求放在消息隊裏,一個一個來處理。
對數據的順序性和一致性有強需求的業務,比如同一張銀行卡同時被多個入口使用,需要保證入賬出賬的順序性,避免出現數據不一致。
3、消息路由: 按照不同的規則,將隊列中消息發送到不同的其他隊列中
通過消息隊列將不同染色的請求發送到不同的服務去操作。這樣達成了流量按照業務拆分的目的。
4、異步處理: 處理一項任務的時候,有 3 個步驟 A、B、C,需要先完成 A 操作, 然後做 B、C 操作。任務執行成功與否強依賴 A 的結果,但不依賴 B、C 的結果。
如果我們使用串行的執行方式,那處理任務的週期就會變長,系統的整體吞吐能力也會降低(在同一個系統中做異步其實也是比較大的開銷),所以使用消息隊列是比較好的辦法。
登錄操作就是典型的場景:A:執行登錄並得到結果、B:記錄登錄日誌、C:將用戶信息和 Token 寫入緩存。執行完 A 就可以從登錄頁跳到首頁了,B、C 讓服務慢慢去消化,不阻塞當前操作。
5、削峯: 將峯值期間的操作削減,比如 A 同學的整個操作流程包含 12 個步驟,後續的 11 個步驟是不需要強關注結果的數據,可以放在消息隊列中。
2 消息中間件的執行原理
2.1 消息中間件的組成
Broker: 消息服務器,作爲 Server 提供消息核心服務
Producer: 消息生產者,業務的發起方,負責生產消息傳輸給 broker,
Consumer: 消息消費者,業務的處理方,負責從 broker 獲取消息並進行業務邏輯處理
Topic: 主題,發佈 / 訂閱模式下的消息統一彙集地,不同生產者向 topic 發送消息,由 MQ 服務器分發到不同的訂閱者,實現消息的廣播
Queue: 隊列,PTP 模式下,特定生產者向特定 queue 發送消息,消費者訂閱特定的 queue 完成指定消息的接收
Message: 消息體,根據不同通信協議定義的固定格式進行編碼的數據包,來封裝業務數據,實現消息的傳輸
這邊以 kafka 爲例子,這是典型的集羣模式,Kafka 通過 Zookeeper 管理集羣配置,選舉 leader,以及在 Consumer Group 發生變化時進行 rebalance。Producer 使用 push 模式將消息發佈到 broker,Consumer 使用 pull 模式從 broker 訂閱並消費消息。
-
producer 負責生產消息
-
consumer 負責消費消息
-
broker 消息服務器,提供消息核心的處理工作
-
zookeeper 用於生產者和消費者的註冊與發現
2.2 消息中間件的模式分類
2.2.1 PTP 點對點
使用 queue 作爲通信載體,消息生產者生產消息發送到 queue 中,然後消息消費者從 queue 中取出並且消費消息。
消息被消費以後,queue 中不再存儲,所以消息消費者不可能消費到已經被消費的消息。Queue 支持存在多個消費者,但是對一個消息而言,只會有一個消費者可以消費。
點對點模式包含三個角色:
-
消息隊列(Queue)
-
發送者 (Sender)
-
接收者 (Receiver)
每個消息都被髮送到一個特定的隊列,接收者從隊列中獲取消息。隊列保留着消息,可以放在內存 中也可以持久化,直到他們被消費或超時。
特點:
-
每個消息只有一個消費者(Consumer)(即一旦被消費,消息就不再在消息隊列中)
-
發送者和接收者之間在時間上沒有依賴性
-
接收者在成功接收消息之後需向隊列應答成功
-
利用 FIFO 先進先出的特性,可以保證消息的順序性。
2.2.2 Pub/Sub 發佈訂閱(廣播)
使用 topic 作爲通信載體,消息生產者(發佈)將消息發佈到 topic 中,同時有多個消息消費者(訂閱)消費該消息。和點對點方式不同,發佈到 topic 的消息會被所有訂閱者消費。
queue 實現了負載均衡,將 producer 生產的消息發送到消息隊列中,由多個消費者消費。但一個消息只能被一個消費者接受,當沒有消費者可用時,這個消息會被保存直到有一個可用的消費者。
發佈訂閱模型包含三個角色:
-
主題(Topic)
-
發佈者(Publisher)
-
訂閱者(Subscriber)
多個發佈者將消息發送到 Topic,系統將這些消息傳遞給多個訂閱者。
特點:
-
每個消息可以有多個消費者:和點對點方式不同,發佈消息可以被所有訂閱者消費
-
發佈者和訂閱者之間有時間上的依賴性。
-
針對某個主題(Topic)的訂閱者,它必須創建一個訂閱者之後,才能消費發佈者的消息。
-
爲了消費消息,訂閱者必須保持運行的狀態。
2.3 消息中間件的優勢
系統解耦:交互系統之間沒有直接的調用關係,只是通過消息傳輸,故系統侵入性不強,耦合度低。
提高系統響應時間:例如原來的一套邏輯,可將緊急重要(需要立刻響應)的業務放到該調用方法中,響應要求不高的使用消息隊列,放到 MQ 隊列中,供消費者處理。
爲大數據處理架構提供服務:通過消息作爲整合,大數據的背景下,消息隊列還與實時處理架構整合,爲數據處理提供性能支持。
2.4 消息中間件常用協議
AMQP 協議、MQTT 協議、STOMP 協議、XMPP 協議、其他基於 TCP/IP 自定義的協議消息中間件的組成
2.4.1 AMQP
AMQP 即 Advanced Message Queuing Protocol,是應用層協議的一個開放標準,爲面向消息的中間件設計。消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。AMQP 的主要特徵是面向消息、隊列、路由(包括點對點和發佈 / 訂閱)、可靠性、安全。
優點:可靠、通用。
2.4.2 MQTT
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是 IBM 開發的一個即時通訊協議,有可能成爲物聯網的重要組成部分。該協議支持所有平臺,幾乎可以把所有聯網物品和外部連接起來,被用來當做傳感器和致動器(比如通過 Twitter 讓房屋聯網)的通信協議。
優點:格式簡潔、佔用帶寬小、移動端通信、PUSH、嵌入式系統
2.4.3 STOMP
STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息協議,是一種爲 MOM(Message Oriented Middleware,面向消息的中間件) 設計的簡單文本協議。STOMP 提供一個可互操作的連接格式,允許客戶端與任意 STOMP 消息代理(Broker)進行交互。
優點:命令模式(非 topic\queue 模式)
2.4.4 XMPP
XMPP(可擴展消息處理現場協議,Extensible Messaging and Presence Protocol)是基於可擴展標記語言(XML)的協議,多用於即時消息(IM)以及在線現場探測。適用於服務器之間的準即時操作。核心是基於 XML 流傳輸,這個協議可能最終允許因特網用戶向因特網上的其他任何人發送即時消息,
即使其操作系統和瀏覽器不同。
優點:通用公開、兼容性強、可擴展、安全性高,但 XML 編碼格式佔用帶寬大
2.5 主流的消息中間件
常見的消息中間件包括:RabbitMQ、RocketMQ、kafka 等,後面我們會有一篇專門對這幾種中間件的能力和技術參數做一項完整的對比,並給出不同業務場景下的技術選型建議。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/z-b9XaRJTFi3wC2cSMqCYA