核心概念#
RabbitMQ 整體上是一個生產者與消費者模型,主要負責接收、存儲和轉發消息。
RabbitMQ 整體架構
- Producer(生產者)和 Comsumer(消費者)
- 消息組成:
- 消息頭(Label):
- routing-key(路由鍵)
- priority(相對於其他消息的優先權)
- delivery-mode(持久性存儲)
- 消息體(payload)
- 消息頭(Label):
- Exchange(交換器):生產者將消息發給 Exchange,其再將消息路由到一個或多個隊列中,如果路由不到,則返回給生產者或直接丟棄
-
流程:Publish Message + RoutingKey → Exchange → Binding Key → Queue > Comsume
-
常用類型:
-
direct(默認):將消息路由到 BindingKey 與 RoutingKey 完全匹配的 Queue 中。常用於處理有優先級的任務
-
fanout:將消息路由到所有與它綁定的 Queue 中。常用來廣播消息
-
topic:將消息路由到 **BindingKey 和 RoutingKey 相匹配(完全匹配或模糊匹配)** 的隊列中
- BindingKey 和 RoutingKey 是用點號 “.” 分隔的字符串
- BindingKey 中可以存在兩種模糊匹配字符串 “*”(匹配一個單詞) 和 “#”(匹配 0 個或多個單詞)
-
headers(不推薦):依賴消息內容中的 headers 屬性進行匹配,性能差,不實用,基本不用
-
-
- Queue(消息隊列):消息的容器,一個消息可投入一個或多個隊列。
- 消費:支持單個或多個消費者(平均分攤 Round-Robin)訂閱同一隊列
- Binding(綁定):通過 BindingKey 將 Queue 綁定到 Exchange
- 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 機制、死信隊列、消息補償機制
- 消息順序性:
- 拆分為多個 queue,每個 queue 一個 consumer(會造成吞吐量下降)
- consumer 不消費消息,而是根據消息中的關鍵值進行哈希(比如 ID,即相同 ID 下的多條消息),再根據哈希值進行分組到不同的內存 queue 中,最後每組交給不同的 worker 也就是子線程去處理(在消費者內部採用多線程的方式消費)
- 高可用:
- 普通集群:數據都在主節點,從節點只同步主節點中 queue 的 metadata,不同步消息
- 鏡像集群:主從節點數據完全同步