RabbitMQ 理解訊息通訊 交換器和繫結

2021-09-17 23:31:29 字數 2154 閱讀 8146

當你想要將訊息投遞到佇列時,你通過把訊息傳送給交換器來完成。然後,根據確定的規則,rabbitmq將會決定訊息該投遞到哪個佇列,這些規則被稱為路由鍵(routing key)佇列通過路由鍵繫結到交換器,當你把訊息傳送到**伺服器時,訊息將擁有乙個路由鍵(即使是空的)

rabbit也會將其和繫結使用的路由鍵進行匹配,如果匹配的話,那麼訊息將會投遞到佇列,如果路由的訊息不匹配任何繫結模式的話,訊息將進入「黑洞」

每一種型別實現了不同的路由演算法

非常簡單,如果路由鍵匹配的話,訊息就會被投遞到對應的佇列

伺服器必須實現direct型別交換器,包含乙個空白字串名稱的預設交換器,當宣告乙個佇列時,他會自動繫結到預設交換器,並以佇列名稱作為路由鍵。

你可以使用如下**傳送訊息到之前宣告的佇列去,前提是你已經獲得了通道例項:

$channel->basic_publish($msg,'','queue-name');
第乙個引數是你想要傳送的訊息內容,第二個引數是乙個空字串,指定了預設交換器,第三個引數是路由鍵

當預設的direct交換器無法滿足你的需求是,你可以宣告你自己的交換器,只需要傳送exchange.declare命令並設定合適的菜蔬就行了

這種型別的交換器會將收到的訊息廣播到繫結的佇列上

當你傳送一條訊息到fanout交換器時,他會把訊息投遞給所有附加在此交換器的佇列,這允許你對單條訊息做不同的反應

你可以將兩個佇列繫結到圖中的交換器上,乙個用於清楚快取,乙個用於積分獎勵

使用fanout交換器,你唯一需要做的就是為新的消費者寫一段**,然後宣告新的佇列並將其繫結到fanout交換器上,而不用修改傳送方的**

這類交換器允許你實現有趣的訊息通訊場景,它使得來自不同源頭的訊息能夠到達同乙個佇列

讓我們以web應用程式日誌系統作為示例

你擁有不同的日誌級別 例如:error info 和warning

你的程式擁有以下幾個模組:user-profile,image-gallery,msg-inbox等

如果在傳送訊息的動作失敗時,你想要報告乙個error的話,則可以編寫以下**

然後你宣告了乙個msg-inbox-errors佇列,你可以將其繫結到交換器來接收訊息

$channel->queue_bind('msg-inbox-errors','logs-exchange','error.msg-inbox');
目前為止,看起來和使用direct交換器很像

但是如果你想要乙個佇列監聽msg-inbox模組的所有級別的話,你該怎麼做?

你可以通過將新的佇列繫結到已有的同乙個交換器來實現就像下面這樣:

$channel->queue_bind('msg-inbox-logs','logs-exchange','*.msg-inbox');
msg-index-logs佇列將會接收從msg-inbox模組發來的所有error,warning和info日誌

萬用字元

為了實現匹配所有規則,你可以使用「#」

$channel->queue_bind('all-log','log-exchage',『#』)
允許你匹配amqp訊息的header而非路由鍵,除此之外,和direct交換器完全一致,但是效能差很多,因此它並不實用,而且幾乎用不到

我們已經理解了這幾種交換器型別,並能體會amqp的強大之處了,你可以對伺服器的行為程式設計以滿足自己的需求,它既能夠以發布\訂閱模式的設定方式作為佇列伺服器使用,也可以作為rpc伺服器使用

RabbitMQ實戰 理解訊息通訊

前段時間總結完了 深入淺出mybatis 系列,對mybatis有了更全面和深入的了解,在掘金社群也收到了一些博友的喜歡,很高興。另外,短暫的陪產假就要結束了,小寶也二周了,下周二就要投入工作了,希望自己盡快調整過來,加油努力。從本篇開始總結 rabbitmq實戰 系列的閱讀筆記,rabbitmq是...

RabbitMQ實戰 理解訊息通訊

rabbitmq是乙個開源的訊息 和佇列伺服器,可以通過基本協議在完全不同的應用之間共享資料,可以將作業排隊以便讓分布式服務進行處理。本篇介紹下訊息通訊,首先介紹基礎概念,將這些概念對映到amqp協議,然後介紹訊息持久化 傳送方確認模式等訊息可靠性保證。通過本篇介紹,你會了解到 訊息通訊概念 此部分...

RabbitMQ (2) 理解訊息通訊

訊息包含兩部分 有效載荷 payload 和標籤 label 通道是建立在 真實的 tcp連線內的虛擬連線,amqp命令是通過通道傳送出去的 消費者通過以下兩種方式從特定的佇列中接收訊息 a.通過amqp的basic.consume命令訂閱 b.basic.get 確認a.basic.ack 顯示的...