RabbitMQ基礎


上一博客把RabbitMQ的安裝配置介紹了下,今天主要是介紹下RabbitMQ的一些基礎名詞。

一、什么是RabbitMQ?用它能做什么?

1.簡介

AMQP,即Advanced Message Queuing Protocol,高級消息隊列協議,是應用層協議的一個開放標准,為面向消息的中間件設計。消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。AMQP的主要特征是面向消息、隊列、路由(包括點對點和發布/訂閱)、可靠性、安全。RabbitMQ是一個開源的AMQP實現,服務器端用Erlang語言編寫,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。

2.作用

消息中間件之間解耦,以網上商城為例,用戶下單時可能會有大並發量,服務器壓力也會增大,特別是類似雙11的時候,那如何解決呢?可以使用消息隊列將訂單信息放在隊列中,下單后付款需要把訂單信息傳給倉庫並會發送短信或者郵箱,倉庫這邊又聯系着進銷存系統,這樣如果把網上商城系統和進銷存系統都放在一起,那就會更加龐大不利於系統解耦,體現不了高內聚低耦合的思想。同時會把訂單信息通過郵箱或者短信發送給用戶,這樣會調用發送郵件或短信的系統,發送郵件或短信的速度速度有限,高峰時可能會將服務器爆了,這種情況可以使用消息隊列來起到錯峰的作用。

二、名詞介紹

1.ConnectionFactory、Connection、Channel

ConnectionFactory從名詞可以看出Connection工廠,它主要用來創建Connection。Connection客戶端與服務器打交道需要先創建與服務器的鏈接,然后通過管道Channel來進行操作。

2.Queue隊列

RabbitMQ中的消息都只能存儲在Queue中,相同屬性的queue可以重復定義,有以下幾個屬性。
- 持久性:如果啟用,隊列將會在server重啟前都有效。
- 自動刪除:如果啟用,那么隊列將會在所有的消費者停止使用之后自動刪除掉自身。
- 惰性:如果沒有聲明隊列,那么在執行到使用的時候會導致異常,並不會主動聲明。
- 排他性:如果啟用,隊列只能被聲明它的消費者使用

3.生產者消費者模式

生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題,生產者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊,所以生產者生產完數據之后不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列里取,阻塞隊列就相當於一個緩沖區,平衡了生產者和消費者的處理能力。一個生產者可以有多個消費者,例如上面的網上商城的例子中,生產者是網上商城系統的訂單,消費者是倉庫系統、郵件、短信服務系統以及日志系統等。

4.Message acknowledgment消息回執

比如在下單過程中用戶下單后需要給倉庫進銷存系統、郵件服務系統、日志系統等,而每個系統又會創建多個消費者,此時消息隊列並不會就把消息刪除,而是需要發送一個回執,以防止消費者宕機等原因導致消息丟失。這里有一個需要注意的地方就是這里沒有timeout超時的概念,一個消費者處理消息時間再長也不會導致該消息被發送給其他消費者(多個消費者),除非它的RabbitMQ連接斷開,在消費者消費之后要記得發送回執,不然會一直堆積在隊列中,消費者重啟后會重復消費這些消息並重復執行業務邏輯。

5.持久化

RabbitMQ服務器也有重啟或宕機的可能性,為了不讓消息丟失,我們可以將Queue與Message都設置為可持久化的(durable),這樣可以保證絕大部分情況下我們的RabbitMQ消息不會丟失。

6.Prefetch count

使用Prefetch count可以實現負載均衡,多個消費者消費一個消息隊列時,可能每個消費者處理信息的時間快慢不同,不能讓有的累死有的餓死,可以通過設置Prefetch count=1,Queue每次給每個消費者發送一條消息;消費者處理完這條消息后Queue會再給該消費者發送一條消息。

7.Exchange交換機

從名詞理解,類似網絡的交換機,還是以訂單為例,生產者網上商城生產的消息需要給倉庫進銷存系統,郵件系統,日志系統,而每個系統又可以創建多個消費者來處理,每個系統不可能都操作一個消息隊列,那樣的話任何一個消費者系統發送回執就會導致消息丟失,導致其他系統遺漏信息處理,實際上一般是會把消息發給交換機,由Exchange將消息路由到一個或多個Queue中(或者丟棄)。這樣進銷存、郵件、日志系統都分別會有一個消息隊列,這樣就不會導致消息丟失了。

8.Binding、Binding key、routing key

Exchange將消息路由到一個或多個Queue,那如何與消息隊列發生關系呢?那就需要先將消息隊列與交換機綁定到一起,一般會指定一個binding key。當消息隊列與交換機綁定之后,消費者就可以生產消息傳遞給消息隊列,那各個消息如何進入到不同的隊列呢?生產者在將消息發送給Exchange的時候,一般會指定一個routing key,來指定這個消息的路由規則,而這個routing key需要與Exchange Type及binding key聯合使用才能最終生效。在Exchange Type與binding key固定的情況下(在正常使用時一般這些內容都是固定配置好的),我們的生產者就可以在發送消息給Exchange時,通過指定routing key來決定消息流向哪里。當binding key與routing key相匹配時,消息將會被路由到對應的Queue中。RabbitMQ為routing key設定的長度限制為255 bytes。binding key 並不是在所有情況下都生效,它依賴於Exchange Type,比如fanout類型的Exchange就會無視binding key,而是將消息路由到所有綁定到該Exchange的Queue.

9.Exchange Types

RabbitMQ一般的Exchange Type有fanout、direct、topic、headers這四種。fanout、direct、topic比較常用headers並不常用。

1.fanout:它會把所有發送到該Exchange的消息路由到所有與它綁定的Queue中.

2.direct: DirectExchange是RabbitMQ Broker的默認Exchange,它有一個特別的屬性對一些簡單的應用來說是非常有用的,在使用這個類型的Exchange時,可以不必指定routing key的名字,在此類型下創建的Queue有一個默認的routing key,這個routing key一般同Queue同名。

3.topic:direct類型的Exchange路由規則是完全匹配binding key與routing key,但這種嚴格的匹配方式在很多情況下不能滿足實際業務需求。topic類型的Exchange在匹配規則上進行了擴展,它與direct類型的Exchage相似,也是將消息路由到binding key與routing key相匹配的Queue中,但這里的匹配規則有些不同,它約定:

1)、routing key為一個句點號“. ”分隔的字符串(我們將被句點號“. ”分隔開的每一段獨立的字符串稱為一個單詞)
2)、binding key與routing key一樣也是句點號“. ”分隔的字符串 binding key中可以存在兩種特殊字符“*”與“#”,用於做模糊匹配,其中“*”用於匹配一個單詞,“#”用於匹配多個單詞(可以是零個)

 


免責聲明!

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



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