RabbitMQ知識點,一篇搞定

前言

分佈式系統中,如何在各個應用之間高效的進行通信,是系統設計中的一個關鍵。

使用 消息代理(message broker) 是一個優雅的解決方案。

RabbitMQ 就是一個被廣泛應用的消息代理,遵循 AMQP協議

接下來我們就瞭解一下:

  • Message Broker 概念
  • AMQP 協議的核心構成
  • 消息轉發的 4 種模式

1. Message Broker

broker 是經紀人的意思,促成賣方、買方的交易,例如房產經紀人。

消息模型中,有消息的生產者、消費者,就相當於賣方、買方。

所以,也需要一個消息經紀人,這就引出了 message broker 的概念。

 RabbitMQ知識點,一篇搞定

message broker 從生產者接收消息,再發送給消費者,這樣,生產者、消費者可以完全隔離。

RabbitMQ 就是一個 message broker

2. AMQP

具體如何傳遞消息?要看使用的消息協議。

RabbitMQ 支持多種協議,其中最重要的是 AMQP(Advanced Message Queuing Protocol)。

AMQP 的概念模型很簡單,包含3個部分:

  • Queue
  • Binding
  • Exchange

當一個消息發佈到 RabbitMQ 後,首先到達 Exchange,然後 Exchange 把消息分配給 Queue,消費者從 Queue 中得到消息。

 RabbitMQ知識點,一篇搞定

AMQP 是一個可編程的協議,我們可以自由配置 exchange, binding, queue。

2.1 Queue 隊列

Queue 是先進先出數據結構。

Queue 是 RabbitMQ 存儲消息的地方。

Queue 可以靈活的配置,例如:

  • 設置 name
  • 配置可靠模式,即使 broker 宕機也可以保障數據安全
  • 消息自動刪除
  • 獨佔模式
  • ……

2.3 Consumer 消費者

一個 queue 可以同時連接多個 consumer。

consumer 既可以自己從 queue 拉取消息,也可以由 queue 主動把消息推給 consumer。

2.4 Binding 綁定

Binding 是 Queue 與 Exchange 建立連接的規則

每個 Queue 都會與一個默認 Exchange 連接,我們可以為這個 Queue 連接更多的 Exchange。

Exchange 通過 Binding 規則,把消息路由到相應的 Queue。

2.5 Exchange

Exchange 是 RabbitMQ 的消息網關。

Exchange 就像是一個接線員,收到消息後決定如何轉發。

主要有 4 種轉發類型:

  • Direct
  • Fanout
  • Topic
  • Header

下面具體瞭解一下。

3. 消息轉發模式

3.1 Direct 直傳

<code>Routing key == Binding key/<code>
  • routing key 是消息的一個屬性。
  • binding key 是綁定 queue 與 exchange 時指定的。
 RabbitMQ知識點,一篇搞定

生產者(綠色球)發送了一個消息,帶著一個 routing key -- img.resize。

當消息到達 exchange(桔色球)後,exchange 會查找所有帶著 img.resize 這個 Binding key 的 queue。

找到匹配的 queue 之後,消息就會被髮送給這些 queue。

如果沒找到,消息會被退回給生產者,或者丟棄。

消息到達指定的 queue 之後,會以輪詢的形式分派給消費者(resizer.1/resizer.2),確保負載均衡。

3.2 Fanout 扇形

 RabbitMQ知識點,一篇搞定

此方式會忽略 routing key,把消息分派給所有連接的 queue。

最常見的場景就是消息廣播

注意,此方式是 exchange 廣播給 queue,不是 queue 廣播給 consumer。queue 到 consumer 還是輪詢的方式。

3.3 Topic 主題

routing key 與 binding key 進行模式匹配。

<code>Routing key == Pattern in binding key/<code>

RabbitMQ 使用 * 和 # 這2個通配符。

* - 匹配一個詞。

# - 匹配 0 個或多個詞。

 RabbitMQ知識點,一篇搞定

routing key 為 logs.error 的消息,匹配 binding key -- logs.error 和 logs.*,所以消息會進入 "only error" 和 "alllogs"。

 RabbitMQ知識點,一篇搞定

routing key 為 logs.success 的消息,匹配binding key -- #success 和 logs.*,所以消息會進入 "only success" 和 "alllogs"。

這種形式有非常多的應用場景,可以用於發佈-訂閱模式、將相關數據分發給期望的 worker 等等。

3.4 Header

一種特殊類型的 exchange,基於消息頭中的 key 進行路由。

使用這種方式後,就會忽略消息的 routing key 屬性。

對一個 header exchange 創建 binding 時,可以對一個 queue 綁定多個 header,這種情況下,消息生產者需要告訴 RabbitMQ 匹配哪些 key,producer 可以指定一個標識 x-match,值可以是:

  • any - 只有一個值應該匹配。
  • all - 所有值都必須匹配。

4. 消息確認

消息到達目的地之後,broker 應該從隊列中將其刪除,這是為了防止消息過多導致溢出。

刪除消息之前,broker 必須得到確認通知。

有 2 種通知方式:

  • 自動通知:只要 consumer 接收到消息即可,不管是否處理完成。
  • 明確顯示通知:只有在 consumer 發送回來一個確認信息後才可以,這樣保證 consumer 處理完成後再刪除。
 RabbitMQ知識點,一篇搞定


分享到:


相關文章: