RabbitMQ 運轉流程


 在最初狀態下,生產者發送消息的時候

(1) 生產者連接到RabbitMQ Broker , 建立一個連接( Connection) ,開啟一個信道(Channel)

(2) 生產者聲明一個交換器,並設置相關屬性,比如交換機類型、是否持久化等

(3) 生產者聲明一個隊列井設置相關屬性,比如是否排他、是否持久化、是否自動刪除等

( 4 ) 生產者通過路由鍵將交換器和隊列綁定起來

( 5 ) 生產者發送消息至RabbitMQ Broker,其中包含路由鍵、交換器等信息

(6) 相應的交換器根據接收到的路由鍵查找相匹配的隊列。

( 7 ) 如果找到,則將從生產者發送過來的消息存入相應的隊列中。

(8) 如果沒有找到,則根據生產者配置的屬性選擇丟棄還是回退給生產者

(9) 關閉信道。

(1 0) 關閉連接。

消費者接收消息的過程:

(1)消費者連接到RabbitMQ Broker ,建立一個連接(Connection ) ,開啟一個信道(Channel) 。

(2) 消費者向RabbitMQ Broker 請求消費相應隊列中的消息,可能會設置相應的回調函數,
以及做一些准備工作

(3)等待RabbitMQ Broker 回應並投遞相應隊列中的消息, 消費者接收消息。

(4) 消費者確認( ack) 接收到的消息。

( 5) RabbitMQ 從隊列中刪除相應己經被確認的消息。

( 6) 關閉信道。

( 7) 關閉連接。

如圖2-9 所示,我們又引入了兩個新的概念: Connection 和Channel 。我們知道無論是生產
者還是消費者,都需要和RabbitMQ Broker 建立連接,這個連接就是一條TCP 連接,也就是
Connection 。一旦TCP 連接建立起來,客戶端緊接着可以創建一個AMQP 信道(Channel) ,每
個信道都會被指派一個唯一的D 。信道是建立在Connection 之上的虛擬連接, RabbitMQ 處理
的每條AMQP 指令都是通過信道完成的。

 

我們完全可以直接使用Connection 就能完成信道的工作,為什么還要引入信道呢?試想這
樣一個場景, 一個應用程序中有很多個線程需要從RabbitMQ 中消費消息,或者生產消息,那
么必然需要建立很多個Connection ,也就是許多個TCP 連接。然而對於操作系統而言,建立和
銷毀TCP 連接是非常昂貴的開銷,如果遇到使用高峰,性能瓶頸也隨之顯現。RabbitMQ 采用
類似NIO' (Non-blocking 1/0) 的做法,選擇TCP 連接復用,不僅可以減少性能開銷,同時也
便於管理。

NIO' ,也稱非阻塞UO , 包含三大核心部分Channel (信道)、Buffer (緩沖區)和Selector (選擇器). NIO 基於Channel 和
Buffer 進行操作,數據總是從信道讀取數據到緩沖區中,或者從緩沖區寫入到信道中。Selector 用於監聽多個信道的事件(比
如連接打開,數據到達等)。因此,單線程可以監聽多個數據的信道。NIO 中有一個很有名的Reactor 模式,有興趣的讀者可以
深入研究。

每個線程把持一個信道,所以信道復用了Connection 的TCP 連接。同時RabbitMQ 可以確
保每個線程的私密性,就像擁有獨立的連接一樣。當每個信道的流量不是很大時,復用單一的
Connection 可以在產生性能瓶頸的情況下有效地節省TCP 連接資源。但是當信道本身的流量很
大時,這時候多個信道復用一個Connection 就會產生性能瓶頸,進而使整體的流量被限制了。
此時就需要開辟多個Connection ,將這些信道均攤到這些Connection 中, 至於這些相關的調優
策略需要根據業務自身的實際情況進行調節.

信道在AMQP 中是一個很重要的概念,大多數操作都是在信道這個層面展開的。在代碼清單
1-1 中也可以看出一些端倪,比如chan ne l . exchangeDeclare 、channel . queueDeclare 、
channel . basicPublish 和channel . basicConsume 等方法。RabbitMQ 相關的API 與AMQP
緊密相連,比如channel.basicPublish 對應AMQP 的Basic.Publish 命令.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM