一、交換機
交換機主要包括如下4種類型:
Direct exchange(直連交換機)
Fanout exchange(扇型交換機)
Topic exchange(主題交換機)
Headers exchange(頭交換機)
另外RabbitMQ默認定義了一些交換機:
默認交換機
amq.* exchanges
還有一類特殊的交換機:Dead Letter Exchange(死信交換機)
1.1 Direct exchange(直連交換機)
將消息的routing key與隊列的binding key進行精確匹配,匹配上則發送到相應隊列,可以發送到多個隊列,若無匹配,則轉發隊列失敗。
1.2 Fanout exchange(扇型交換機)
將消息發送到所有隊列,不會計算消息的routing key與隊列的binding key是否匹配。
1.3 Topic exchange(主題交換機)
將消息的routing key與隊列的binding key進行模糊匹配,匹配上則發送到相應隊列,可以發送到多個隊列,若無匹配,則轉發隊列失敗。
binding key支持*和#,*只能匹配一個詞,#可以匹配多個詞。
例如:
order.*
可以匹配order.123456
,不能匹配order.cancel.123456
order.#
可以匹配order.123456
和order.cancel.123456
說明:以上例子
order.*
是binding key,order.123456
是routing key
1.4 Headers exchange(頭交換機)
不處理路由鍵,而是根據發送的消息內容中的headers屬性進行匹配。在綁定Queue與Exchange時指定一組鍵值對;當消息發送到RabbitMQ時會取到該消息的headers與Exchange綁定時指定的鍵值對進行匹配;如果完全匹配則消息會路由到該隊列,否則不會路由到該隊列。headers屬性是一個鍵值對,可以是HashTable,鍵值對的值可以是任何類型。而fanout,direct,topic 的路由鍵都需要要字符串形式的。
匹配規則x-match有下列兩種類型:
x-match = all :表示所有的鍵值對都匹配才能接受到消息
x-match = any :表示只要有鍵值對匹配就能接受到消息
1.5 其它交換機
在RabbitMQ默認定義一些交換機,主要如下:
1.5.1 默認交換機
默認交換機(default exchange)實際上是一個由RabbitMQ預先聲明好的名字爲空字符串的直連交換機(direct exchange)。它有一個特殊的屬性使得它對於簡單應用特別有用處:那就是每個新建隊列(queue)都會自動綁定到默認交換機上,綁定的路由鍵(routing key)名稱與隊列名稱相同。
如:當你聲明瞭一個名爲”hello”的隊列,RabbitMQ會自動將其綁定到默認交換機上,綁定(binding)的路由鍵名稱也是爲”hello”。因此,當攜帶着名爲”hello”的路由鍵的消息被髮送到默認交換機的時候,此消息會被默認交換機路由至名爲”hello”的隊列中。即默認交換機看起來貌似能夠直接將消息投遞給隊列,如同我們之前文章裏看到一例子。
1.5.2 amq.*的名稱的交換機
這些是RabbitMQ默認創建的交換機。這些隊列名稱被預留做RabbitMQ內部使用,不能被應用使用,否則拋出403 (ACCESS_REFUSED)錯誤
1.5.3 Dead Letter Exchange(死信交換機)
在默認情況,如果消息在投遞到交換機時,交換機發現此消息沒有匹配的隊列,則這個消息將被悄悄丟棄。爲了解決這個問題,RabbitMQ中有一種交換機叫死信交換機。當消費者不能處理接收到的消息時,將這個消息重新發布到另外一個隊列中,等待重試或者人工干預。這個過程中的exchange和queue就是所謂的”Dead Letter Exchange 和 Queue”
1.5.4 交換機的屬性
除交換機類型外,在聲明交換機時還可以附帶許多其他的屬性,其中最重要的幾個分別是:
Name:交換機名稱
Durability:是否持久化。如果持久性,則RabbitMQ重啓後,交換機還存在
Auto-delete:當所有與之綁定的消息隊列都完成了對此交換機的使用後,刪掉它
Arguments:擴展參數
二、隊列
隊列綁定到交換機上,可以設置一個binding key,也可以不設置。
-
當不設置binding key時,若隊列綁定到直連交換機或主題交換機,那麼生產者發送消息時不設置routing key,才能收到消息。
-
當設置binding key時,若隊列綁定到直連交換機或主題交換機,那麼生產者發送消息時需要設置routing key,且被binding key匹配上,才能收到消息。
-
當隊列綁定到扇形交換機,隊列的binding key與消息的routing key無效,不管隊列是否設置binding key和生產者是否設置routing key,生產者發送到扇形交換機的消息,隊列都能收到。
三、消費者
消費者綁定到某個隊列上,當有多個消費者綁定同一隊列時,會使用輪循的方式將消息分發給各消費者。
四、生產者
生產者往交換機發送消息,可附帶一個routing key,也可以不帶。
-
發送消息到直連交換機時,不帶routing key,消息只會轉發到未設置binding key的隊列;帶了routing key,消息只會轉發到設置了相同binding key的隊列。
-
發送消息到扇形交換機時,帶不帶routing key,消息都會轉發給所有隊列。
-
發送消息到主題交換機時,不帶routing key,消息只會轉發到未設置binding key的隊列;帶了routing key,消息會按照routing key轉發被binding key匹配的隊列。一般binding key是一個模糊匹配表達式(如:order.*,order.#),routing key是一個精確值(如:order.123456,order.cancel.123456)
參考資料