當前位置:
首頁 > 最新 > RabbitMq運行原理淺析

RabbitMq運行原理淺析

1.RabbitMq簡介

AMQP,即Advanced Message Queuing Protocol,高級消息隊列協議,是應用層協議的一個開放標準,為面向消息的中間件設計。消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。AMQP的主要特徵是面向消息、隊列、路由(包括點對點和發布/訂閱)、可靠性、安全。

RabbitMQ是一個開源的AMQP實現,伺服器端用Erlang語言編寫,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用於在分散式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。下面將重點介紹RabbitMQ中的一些基礎概念,了解了這些概念,是使用好RabbitMQ的基礎。

2.RabbitMq模型

Server(broker)

接受客戶端連接,實現AMQP消息隊列和路由功能的進程,可以理解為郵局。

Virtual Host

其實是一個虛擬概念,類似於許可權控制組,一個Virtual Host裡面可以有若干個Exchange和Queue,當多個不同的用戶使用同一個RabbitMQ server提供的服務時,可以劃分出多個vhost,每個用戶在自己的vhost創建exchange/queue等,就好比於tomcat中webapps目錄下可以部署多個web項目。

Exchange

接受生產者發送的消息,並根據Binding規則將消息路由給伺服器中的隊列,就好比郵遞員。Exchange有4種類型,direct(默認),fanout, topic, 和headers,不同類型的Exchange轉發消息的策略有所區別:

1)、Direct 直接交換器,工作方式類似於單播,Exchange會將消息發送完全匹配ROUTING_KEY的Queue。

2)、fanout廣播是式交換器,不管消息的ROUTING_KEY設置為什麼,Exchange都會將消息轉發給所有綁定的Queue。

3)、topic主題交換器,工作方式類似於組播,Exchange會將消息轉發和ROUTING_KEY匹配模式相同的所有隊列,比如,ROUTING_KEY為user.stock的Message會轉發給綁定匹配模式為 * .stock,user.stock, * . * 和#.user.stock.#的隊列。( * 表是匹配一個任意片語,#表示匹配0個或多個片語)。

4)、headers消息體的header匹配(ignore)。

Message Queue

消息只能存儲在隊列(queue)中。儘管消息在rabbitMQ和應用程序間流通,但是隊列卻是存在於RabbitMQ內部。一個隊列不受任何限制,它可以存儲你想要存儲的消息量,它本質上是一個無限的緩衝區。多個生產者可以向同一個隊列發送消息,多個消費者可以嘗試從同一個消息隊列中接收數據。消息隊列,提供了FIFO的處理機制,具有緩存消息的能力。Rabbitmq中,隊列消息可以設置為持久化,臨時或者自動刪除。

1)、設置為持久化的隊列,queue中的消息會在server本地硬碟存儲一份,防止系統crash,數據丟失。

2)、設置為臨時隊列,queue中的數據在系統重啟之後就會丟失。

3)、設置為自動刪除的隊列,當不存在用戶連接到server,隊列中的數據會被自動刪除。

Message

由Header和Body組成,Header是由生產者添加的各種屬性的集合,包括Message是否被持久化、由哪個Message Queue接受、優先順序是多少等,就好比於郵箱裡面的信件。而Body是真正需要傳輸的APP數據,就像信件裡面的信紙。

Binding

Binding聯繫了Exchange與Message Queue。Exchange在與多個Message Queue發生Binding後會生成一張路由表,路由表中存儲著Message Queue所需消息的限制條件即Binding Key。當Exchange收到Message時會解析其Header得到Routing Key,Exchange根據Routing Key與Exchange Type將Message路由到Message Queue。Binding Key由Consumer在Binding Exchange與Message Queue時指定,而Routing Key由Producer發送Message時指定,兩者的匹配方式由Exchange Type決定,就好比於郵件上面的地址。

Connection

連接,對於RabbitMQ而言,其實就是一個位於客戶端和Broker之間的TCP連接。

Channel

信道,僅僅創建了客戶端到Broker之間的連接後,客戶端還是不能發送消息的。需要為每一個Connection創建Channel,AMQP協議規定只有通過Channel才能執行AMQP的命令。一個Connection可以包含多個Channel。之所以需要Channel,是因為TCP連接的建立和釋放都是十分昂貴的,如果一個客戶端每一個線程都需要與Broker交互,如果每一個線程都建立一個TCP連接,暫且不考慮TCP連接是否浪費,就算操作系統也無法承受每秒建立如此多的TCP連接,可以簡單的理解為線程池中的一個個線程。

3.通信過程

假設P1和C1註冊了相同的Broker,Exchange和Queue。P1發送的消息最終會被C1消費。基本的通信流程大概如下所示:

P1生產消息,發送給伺服器端的Exchange

Exchange收到消息,根據ROUTINKEY,將消息轉發給匹配的Queue1

Queue1收到消息,將消息發送給訂閱者C1

C1收到消息,發送ACK給隊列確認收到消息

Queue1收到ACK,刪除隊列中緩存的此條消息

Consumer收到消息時需要顯式的向rabbit broker發送basic.ack消息或者consumer訂閱消息時設置auto_ack參數為true。在通信過程中,隊列對ACK的處理有以下幾種情況:

如果consumer接收了消息,發送ack,rabbitmq會刪除隊列中這個消息,發送另一條消息給consumer。

如果cosumer接受了消息, 但在發送ack之前斷開連接,rabbitmq會認為這條消息沒有被deliver,在consumer在次連接的時候,這條消息會被redeliver。

如果consumer接受了消息,但是程序中有bug,忘記了ack,rabbitmq不會重複發送消息。

rabbitmq2.0.0和之後的版本支持consumer reject某條(類)消息,可以通過設置requeue參數中的reject為true達到目地,那麼rabbitmq將會把消息發送給下一個註冊的consumer。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 全球大搜羅 的精彩文章:

145平的美式風格,不一樣的設計,原來還能這樣裝修
客廳裝修6大風水忌諱

TAG:全球大搜羅 |