關概念介紹
RabbitMQ 整體上是一個生産者與消費者模型,主要負責接收,存儲和轉發消息。可以把消息傳遞的過程想象成:當你将一個包裹送到郵局,郵局會暫存并最終将郵件通過郵差送到收件人的手上, RabbitMQ 就好比由郵局,郵箱和郵差組成的一個系統。從計算機術語層面來說RabbitMQ 模型更像是一種交換機模型。
RabbitMQ 模型架構
生産者和消費者
Producer:生産者,就是投遞消息的一方。生産者建立消息,然後釋出到 RabbitMQ 中。消息般可以包含2個部分:消息體和标簽Label。消息體也可以稱之為payload,在實際應用中,消息體一般是一個帶有業務邏輯結構的資料,比如一個 JSON 字元串。當然可以進一步對這個消息體進行序列化操作。消息的标簽用來表述這條消息,比如一個交換器的名稱和一個路由鍵。生産者把消息交由RabbitMQ,RabbitMQ之後會根據标簽把消息發送給感興趣的消費者Consumer。
Consumer:消費者就是接收消息的一方。
消費者連接配接到RabbitMQ伺服器,并訂閱到隊列上。當消費者消費一條消息時,隻是消費消息的消息體 payload。在消息路由的過程中,消息的标簽會丢棄,存入到隊列中的消息隻有消息體,消費者也隻會消費到消息體,也就不知道消息的生産者是誰,當然消費者也不需要知道。
Broker:消息中間件的服務節點。
對于RabbitMQ來說,RabbitMQ Broker可以簡單看作一個RabbitMQ服務節點,或者 RabbitMQ 服務執行個體。大多數情況下RabbitMQ Broker看作一台RabbitMQ伺服器。
生産者将消息存入RabbitMQ Broker,以及消費者從Broker中消費資料的整個流程
隊列
Queue:隊列是RabbitMQ内部對象,用于存儲消息。RabbitMQ中消息都隻能存儲在隊列中,RabbitMQ 的生産者生産消息井最終技遞到隊列中,消費者可以從隊列中擷取消息并消費。多個消費者可以訂閱同一個隊列,這時隊列中的消息會被平均分攤 (Round-Robin,即輪詢)給多個消費者進行處理,而不是每個消費者都收到所有的消息井處理。
交換器、路由鍵、綁定
Exchange:交換器,在上面隊列介紹中暫時可以了解成生産者将消息投遞到隊列中,實際上
這個在 RabbitMQ中不會發生。真實情況是,生産者将消息發送到 Exchange,由交換器将消息路由到一個或者多個隊列中。如果路由不到,或許會傳回給生産者,或許直接丢棄。
RoutingKey:路由鍵。生産者将消息發給交換器的時候,一般會指定一個RoutingKey,用來指定這個消息的路由規則,而這個RoutingKey需要與交換器類型和綁定鍵 (BindingKey)合使用才能最終生效。在交換器類型和綁定鍵 (BindingKey) 固定的情況下,生産者可以在發送消息給交換器時,通過指定RoutingKey來決定消息流向哪裡。
Binding:綁定。RabbitMQ中通過綁定将交換器與隊列關聯起來,在綁定的時候一般會指定一個綁定鍵 BindingKey,這樣RabbitMQ就知道如何正确将消息路由到隊列了。
生産者将消息發送給交換器時,需要一 RoutingKey,當BindingKey和RoutingKey相匹時,消息會被路由 到對應的隊列中。在綁定多個隊列到同一個交換器的時候這些綁定允許使用相同的BindingKey。BindingKey并不是在所有的情況下都生效,它依賴于交換器類型,比如fanout類型的交換器就會無BindingKey而是将消息路由到所有綁定到該交換器的隊列中。在某些情形下(如使用direct交換器類型)RoutingKey和BindingKey可以看作同一個東西。
交換器類型
RabbitMQ常用的交換器類型有fanout,direct,topic,headers四種。
Fanout Exchange:它會把所有發送到該交換器的消息路由到所有與該交換器綁定的隊列中,無視BindingKey。
Direct Exchange:它會把消息路由到那些BindingKey和RoutingKey完全比對的隊列中。
Topic Exchange:将路由鍵和某模式進行比對。此時隊列需要綁定要一個模式上。符号“#”比對一個或多個詞,符号“”比對一個詞。是以“audit.#”能夠比對到“audit.irs.corporate”,但是“audit.” 隻會比對到“audit.irs”。(具體的RoutingKey和模糊的BindingKey進行模糊比對)
Nameless exchange(匿名轉發)
使用預設的轉發器,轉發器名為空字元串"",也可以将消息發送到隊列。
channel.BasicPublish("", “hello”, null, mseeage.GetBytes());
RabbitMQ 運轉流程
生産者流程:
- 生産者連接配接到 RabbitMQ Broker 建立一個連接配接( Connection) ,開啟 個信道 (Channel)。
- 生産者聲明一個交換器 ,并設定相關屬性,比如交換機類型、是否持久化等。
- 生産者聲明 個隊列井設定相關屬性,比如是否排他、是否持久化、是否自動删除等。
- 生産者通過路由鍵将交換器和隊列綁定起來。
- 生産者發送消息至 RabbitMQ Broker,其中包含路由鍵、換器等資訊。
- 相應的交換器根據接收到的路由鍵查找相比對的隊列。
- 如果找到 ,則将從生産者發送過來的消息存入相應的隊列中。如果沒有找到 ,則根據生産者配置的屬性選擇丢棄還是回退給生産者。
- 關閉信道。關閉連接配接。
消費者流程:
- 消費者連接配接到 RabbitMQ Broker,建立一個連接配接(Connection),開啟 個信道(Channel)。
-
消費者向 RabbitMQ Broker 請求消費相應隊列中的消息,可能會設定相應的回調函數,
以及做 些準備工作。
- 等待 RabbitMQ Broker 回應并投遞相應隊列中的消息, 消費者接收消息。
- 消費者确認(ack) 接收到的消息。
- RabbitMQ 從隊列中删除相應己經被确認的消息。
- 關閉信道。關閉連接配接。
無論是生者還是消費者,都需要和 RabbitMQ Broker 建立連接配接,這個連接配接就是一條 TCP 連接配接,也就是
Connection。一旦 TCP 連接配接建立起來,用戶端緊接着可以建立一個 AMQP 信道 (Channel) ,每個信道都會被指派一個唯一ID。信道是建立在 Connection 之上的虛拟連接配接, RabbitMQ 處理的每條 AMQP 指令都是通過信道完成的。
AMQP 協定介紹
RabbitMQ 就是 AMQP (Advanced Message Queuing Protocol,進階消息隊列協定) 的 Erlang 的實作。AMQP 的模型架構和 RabbitMQ 的模型架構是一樣的,生産者将消息發送給交換器,交換器和隊列綁定 。當生産者發送消息時所攜帶的 RoutingKey 與綁定時 BindingKey 比對時,消息即被存入相應的隊列之中。消費者可以訂閱相應的隊列來擷取消息。
AMQP生産者流轉過程
AMQP消費者流轉過程
AMQP指令總覽
名稱 | 是否包含内容體 | 對應用戶端中的方法 | 簡要描述 |
---|---|---|---|
Connection.start | 否 | factory.newConnection | 建立連接配接相關 |
Connection.Start-Ok | 否 | 同上 | 同上 |
Connection.Tune | 否 | 同上 | 同上 |
Connection.Tune-Ok | 否 | 同上 | 同上 |
Connection.Open | 否 | 同上 | 同上 |
Connection.Open-Ok | 否 | 同上 | 同上 |
Connection.Close | 否 | connection.close | 關閉連接配接 |
Connection.Close-Ok | 否 | 同上 | 同上 |
Channel.Open | 否 | connection.openChannel | 開啟信道 |
Channel.Open-Ok | 否 | 同上 | 同上 |
Cbannel.Close | 否 | channel.close | 關閉信道 |
Channel.Close-Ok | 否 | 同上 | 同上 |
Exchange.Declare | 否 | channel.exchangeDeclare | 聲明交換器 |
Exchange.Declare-Ok | 否 | 同上 | 同上 |
Exchange.Delete | 否 | channel.ExchangeDelete | 删除交換器 |
Exchangge.Delete-Ok | 否 | 同上 | 同上 |
Exchange.Bind | 否 | channel.ExchanggeBind | 交換器與交換器綁定 |
Exchange.Bind-Ok | 否 | 同上 | 同上 |
Exchange.Unbind | 否 | channel.ExchangeUnbind | 交換器與交換器解綁 |
Exchange.Unbind-Ok | 否 | 同上 | 同上 |
Queue.Declare | 否 | channel.queueDeclare | 聲明隊列 |
Queue. Declare-Ok | 否 | 同上 | 同上 |
Queue.Bind | 否 | channel.queueBind | 隊列與交換器綁定 |
Queue.Bind-Ok | 否 | 同上 | 同上 |
Queue.Purge | 否 | channel.queuePurge | 清除隊列中的内容 |
Queue.Purge-Ok | 否 | 同上 | 同上 |
Queue.Delete | 否 | channel.queueDelete | 删除隊列 |
Queue.Delete-Ok | 否 | 同上 | 同上 |
Queue.Unbind | 否 | channel.queueUnbind | 隊列與交換器解綁 |
Queue.Unbind-Ok | 否 | 同上 | 同上 |
Basic.Qos | 否 | channel.basicQos | 設定未被确認消費的個數 |
Basic.Qos-Ok | 否 | 同上 | 同上 |
Basic.Consume | 否 | channel.basicConsume | 消費消息(推模式) |
BasiιConsurne-Ok | 否 | 同上 | 同上 |
Basic.Cancel | 否 | channel.basicCancel | 取消 |
Basic.Cancel-Ok | 否 | 同上 | 同上 |
Basic.Publish | 是 | channel.basicPublish | 發送消息 |
Basic.Return | 是 | 無 | 未能成功路由的消息傳回 |
Basic.Deliver | 是 | 無 | Broker 推送消息 |
Basic.Get | 否 | channel.basicGet | 消費消息(拉模式) |
Basic.Get-Ok | 是 | 同上 | 同上 |
Basic.Ack | 否 | channel.basicAck | 确認 |
Basic.Reject | 否 | channel.basicReject | 拒絕(單條拒絕) |
Basic.Recover | 否 | channel.basicRecover | 請求 Broker 重新發送未被确認的消息 |
Basic.Recover-Ok | 否 | 同上 | 同上 |
Basic.Nack | 否 | channel.basicNack | 拒絕(可批量拒絕) |
Tx.Select | 否 | channel. txSelect | 開啟事務 |
TX.Select-Ok | 否 | 同上 | 同上 |
Tx.Cornmit | 否 | channel. txCommit | 事務送出 |
TX.Commit-Ok | 否 | 同上 | 同上 |
Tx.Rollback | 否 | channel.txRollback | 事務復原 |
TX.Rollback-Ok | 否 | 同上 | 同上 |
Confirrn Select | 否 | channel.confinnSelect | 開啟發送端确認模式 |
Confinn.Select-Ok | 否 | 同上 | 同上 |
總結
本章主要講述的是 RabbitMQ 的入門知識,首先介紹了生産者(Producer)、消費者(Consumer)、隊列 (Queue) 、交換器 (Exchange) 、路由鍵 (RoutingKey)、綁定 (Binding) 連接配接 (Connection) 和信道(Channel) 等基本術語,還介紹了交換器的類型 fanout、direct、topic、headers。通過介紹 RabbitMQ 的運轉流程來加深對基本術語的了解。