上一博客把RabbitMQ的安裝配置介紹了下,今天主要是介紹下RabbitMQ的一些基礎(chǔ)名詞。
一、什么是RabbitMQ?用它能做什么?
1.簡(jiǎn)介
AMQP,即Advanced Message Queuing Protocol,高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開(kāi)放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)。消息中間件主要用于組件之間的解耦,消息的發(fā)送者無(wú)需知道消息使用者的存在,反之亦然。AMQP的主要特征是面向消息、隊(duì)列、路由(包括點(diǎn)對(duì)點(diǎn)和發(fā)布/訂閱)、可靠性、安全。RabbitMQ是一個(gè)開(kāi)源的AMQP實(shí)現(xiàn),服務(wù)器端用Erlang語(yǔ)言編寫(xiě),支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。
2.作用
消息中間件之間解耦,以網(wǎng)上商城為例,用戶下單時(shí)可能會(huì)有大并發(fā)量,服務(wù)器壓力也會(huì)增大,特別是類似雙11的時(shí)候,那如何解決呢?可以使用消息隊(duì)列將訂單信息放在隊(duì)列中,下單后付款需要把訂單信息傳給倉(cāng)庫(kù)并會(huì)發(fā)送短信或者郵箱,倉(cāng)庫(kù)這邊又聯(lián)系著進(jìn)銷(xiāo)存系統(tǒng),這樣如果把網(wǎng)上商城系統(tǒng)和進(jìn)銷(xiāo)存系統(tǒng)都放在一起,那就會(huì)更加龐大不利于系統(tǒng)解耦,體現(xiàn)不了高內(nèi)聚低耦合的思想。同時(shí)會(huì)把訂單信息通過(guò)郵箱或者短信發(fā)送給用戶,這樣會(huì)調(diào)用發(fā)送郵件或短信的系統(tǒng),發(fā)送郵件或短信的速度速度有限,高峰時(shí)可能會(huì)將服務(wù)器爆了,這種情況可以使用消息隊(duì)列來(lái)起到錯(cuò)峰的作用。
二、名詞介紹
1.ConnectionFactory、Connection、Channel
ConnectionFactory從名詞可以看出Connection工廠,它主要用來(lái)創(chuàng)建Connection。Connection客戶端與服務(wù)器打交道需要先創(chuàng)建與服務(wù)器的鏈接,然后通過(guò)管道Channel來(lái)進(jìn)行操作。
2.Queue隊(duì)列
RabbitMQ中的消息都只能存儲(chǔ)在Queue中,相同屬性的queue可以重復(fù)定義,有以下幾個(gè)屬性。
- 持久性:如果啟用,隊(duì)列將會(huì)在server重啟前都有效。
- 自動(dòng)刪除:如果啟用,那么隊(duì)列將會(huì)在所有的消費(fèi)者停止使用之后自動(dòng)刪除掉自身。
- 惰性:如果沒(méi)有聲明隊(duì)列,那么在執(zhí)行到使用的時(shí)候會(huì)導(dǎo)致異常,并不會(huì)主動(dòng)聲明。
- 排他性:如果啟用,隊(duì)列只能被聲明它的消費(fèi)者使用
3.生產(chǎn)者消費(fèi)者模式
生產(chǎn)者消費(fèi)者模式是通過(guò)一個(gè)容器來(lái)解決生產(chǎn)者和消費(fèi)者的強(qiáng)耦合問(wèn)題,生產(chǎn)者和消費(fèi)者彼此之間不直接通訊,而通過(guò)阻塞隊(duì)列來(lái)進(jìn)行通訊,所以生產(chǎn)者生產(chǎn)完數(shù)據(jù)之后不用等待消費(fèi)者處理,直接扔給阻塞隊(duì)列,消費(fèi)者不找生產(chǎn)者要數(shù)據(jù),而是直接從阻塞隊(duì)列里取,阻塞隊(duì)列就相當(dāng)于一個(gè)緩沖區(qū),平衡了生產(chǎn)者和消費(fèi)者的處理能力。一個(gè)生產(chǎn)者可以有多個(gè)消費(fèi)者,例如上面的網(wǎng)上商城的例子中,生產(chǎn)者是網(wǎng)上商城系統(tǒng)的訂單,消費(fèi)者是倉(cāng)庫(kù)系統(tǒng)、郵件、短信服務(wù)系統(tǒng)以及日志系統(tǒng)等。
4.Message acknowledgment消息回執(zhí)
比如在下單過(guò)程中用戶下單后需要給倉(cāng)庫(kù)進(jìn)銷(xiāo)存系統(tǒng)、郵件服務(wù)系統(tǒng)、日志系統(tǒng)等,而每個(gè)系統(tǒng)又會(huì)創(chuàng)建多個(gè)消費(fèi)者,此時(shí)消息隊(duì)列并不會(huì)就把消息刪除,而是需要發(fā)送一個(gè)回執(zhí),以防止消費(fèi)者宕機(jī)等原因?qū)е孪G失。這里有一個(gè)需要注意的地方就是這里沒(méi)有timeout超時(shí)的概念,一個(gè)消費(fèi)者處理消息時(shí)間再長(zhǎng)也不會(huì)導(dǎo)致該消息被發(fā)送給其他消費(fèi)者(多個(gè)消費(fèi)者),除非它的RabbitMQ連接斷開(kāi),在消費(fèi)者消費(fèi)之后要記得發(fā)送回執(zhí),不然會(huì)一直堆積在隊(duì)列中,消費(fèi)者重啟后會(huì)重復(fù)消費(fèi)這些消息并重復(fù)執(zhí)行業(yè)務(wù)邏輯。
5.持久化
RabbitMQ服務(wù)器也有重啟或宕機(jī)的可能性,為了不讓消息丟失,我們可以將Queue與Message都設(shè)置為可持久化的(durable),這樣可以保證絕大部分情況下我們的RabbitMQ消息不會(huì)丟失。
6.Prefetch count
使用Prefetch count可以實(shí)現(xiàn)負(fù)載均衡,多個(gè)消費(fèi)者消費(fèi)一個(gè)消息隊(duì)列時(shí),可能每個(gè)消費(fèi)者處理信息的時(shí)間快慢不同,不能讓有的累死有的餓死,可以通過(guò)