核心概念#
RabbitMQ 整體上是一個生產者與消費者模型,主要負責接收、存儲和轉發消息。
RabbitMQ 整體架構
- 生產者(Producer)和消費者(Comsumer)
- 消息組成:
- 消息頭(Label):
- 路由鍵(routing-key)
- 優先級(相對於其他消息的優先權)
- 傳遞模式(持久性存儲)
- 消息體(payload)
- 消息頭(Label):
- 交換器(Exchange):生產者將消息發給交換器,其再將消息路由到一個或多個隊列中,如果路由不到,則返回給生產者或直接丟棄
-
流程:發布消息 + 路由鍵(RoutingKey) → 交換器(Exchange) → 綁定鍵(Binding Key) → 隊列 > 消費
-
常用類型:
-
直接(默認):將消息路由到 綁定鍵(BindingKey)與路由鍵(RoutingKey)完全匹配的隊列中。常用於處理有優先級的任務
-
扇形:將消息路由到所有與它綁定的隊列中。常用來廣播消息
-
主題:將消息路由到 ** 綁定鍵(BindingKey)和路由鍵(RoutingKey)相匹配(完全匹配或模糊匹配)** 的隊列中
- 綁定鍵(BindingKey)和路由鍵(RoutingKey)是用點號 “.” 分隔的字符串
- 綁定鍵(BindingKey)中可以存在兩種模糊匹配字符串 “*”(匹配一個單詞) 和 “#”(匹配 0 個或多個單詞)
-
headers(不推薦):依賴消息內容中的 headers 屬性進行匹配,性能差,不實用,基本不用
-
-
- 隊列(Queue):消息的容器,一個消息可投入一個或多個隊列。
- 消費:支持單個或多個消費者(平均分攤 Round-Robin)訂閱同一隊列
- 綁定(Binding):通過綁定鍵(BindingKey)將隊列綁定到交換器
- Broker(消息中間件的服務節點):一個 RabbitMQ Broker 可以簡單地看作一個 RabbitMQ 服務節點或者 RabbitMQ 服務實例
- 死信交換器(Dead Letter Exchange):當消息在隊列中變成死信(dead message)後,就被發送到死信交換器
- 死信原因:
- 消息被拒(Basic.Reject/ Basic.Nack)且 requeue = false
- 消息 TTL 過期
- 隊列滿了
- 死信原因:
- 延遲隊列:消息在特定時間後才被消費
- 實現方式:
- 使用 RabbitMQ 的死信交換器(Dead Letter Exchange)和消息的存活時間(TTL)
- 使用 RabbitMQ 3.5.7+ 開發的插件(rabbitmq-delayed-message-exchange)
- 實現方式:
- 優先級隊列:RabbitMQ 3.5.0+ 通過
x-max-priority
參數實現。當消費速度大於生產速度且 Broker 沒有堆積的情況下,該參數沒有意義 - 消息傳輸:基於建立在 TCP 連接上的信道(Channel),數量無限制,每個信道在 RabbitMQ 都有唯一的 ID,對應一個線程使用
- 消息可靠性:
- 生產者到 RabbitMQ:事務機制或 Confirm 机制,注意:事務機制和 Confirm 机制是互斥的,兩者不能共存,會導致 RabbitMQ 報錯
- RabbitMQ 自身:持久化、普通集群、鏡像集群
- RabbitMQ 到消費者:basicAck 机制、死信隊列、消息補償機制
- 消息順序性:
- 拆分為多個隊列,每個隊列一個消費者(會造成吞吐量下降)
- 消費者不消費消息,而是根據消息中的關鍵值進行哈希(比如 ID,即相同 ID 下的多條消息),再根據哈希值進行分組到不同的內存隊列中,最後每組交給不同的 worker 也就是子線程去處理(在消費者內部採用多線程的方式消費)
- 高可用:
- 普通集群:數據都在主節點,從節點只同步主節點中隊列的 metadata,不同步消息
- 鏡像集群:主從節點數據完全同步