1.概述
RabbitMQ是一個(gè)消息中間件:它接受并轉(zhuǎn)發(fā)消息。你可以把它當(dāng)做一個(gè)快遞站點(diǎn),當(dāng)你要發(fā)送一個(gè)包裹時(shí),你把你的包裹放到快遞站,快遞員最終會(huì)把你的快遞送到收件人那里,按照這種邏輯RabbitMQ是一個(gè)快遞站,一個(gè)快遞員幫你傳遞快件。RabbitMQ與快遞站的主要區(qū)別在于,它不處理快件而是接收,存儲(chǔ)和轉(zhuǎn)發(fā)消息數(shù)據(jù)。
2.下載
rabbitMQ下載詳情可見(jiàn)
如何下載安裝RabbitMQ
http://www.therapist.net.cn/ask/thread/23689
3.工作原理
4.名詞介紹
Broker:接收和分發(fā)消息的應(yīng)用,RabbitMQ Server就是Message Broker
Connection: publisher / consumer和 broker之間的TCP連接
Channel:如果每一次訪問(wèn)RabbitMQ都建立一個(gè)Connection,在消息量大的時(shí)候建立TCP
Connection的開(kāi)銷(xiāo)將是巨大的,效率也較低。Channel是在connection 內(nèi)部建立的邏輯連接,如果應(yīng)用程序支持多線程,通常每個(gè)thread創(chuàng)建單獨(dú)的channel進(jìn)行通訊,AMQP method包含了channel id 幫助客戶端和message broker識(shí)別 channel,所以channel 之間是完全隔離的。Channel作為輕量級(jí)的Connection極大減少了操作系統(tǒng)建TCP connection的開(kāi)銷(xiāo)
Exchange: message 到達(dá) broker 的第一站,根據(jù)分發(fā)規(guī)則,匹配查詢(xún)表中的 routing key,分發(fā)消息到queue 中去。常用的類(lèi)型有: direct (point-to-point), topic(publish-subscribe) and fanout
(multicast)
Routing Key:生產(chǎn)者將消息發(fā)送到交換機(jī)時(shí)會(huì)攜帶一個(gè)key,來(lái)指定路由規(guī)則
binding Key:在綁定Exchange和Queue時(shí),會(huì)指定一個(gè)BindingKey,生產(chǎn)者發(fā)送消息攜帶的RoutingKey會(huì)和bindingKey對(duì)比,若一致就將消息分發(fā)至這個(gè)隊(duì)列
vHost 虛擬主機(jī):每一個(gè)RabbitMQ服務(wù)器可以開(kāi)設(shè)多個(gè)虛擬主機(jī)每一個(gè)vhost本質(zhì)上是一個(gè)mini版的RabbitMQ服務(wù)器,擁有自己的 "交換機(jī)exchange、綁定Binding、隊(duì)列Queue",更重要的是每一個(gè)vhost擁有獨(dú)立的權(quán)限機(jī)制,這樣就能安全地使用一個(gè)RabbitMQ服務(wù)器來(lái)服務(wù)多個(gè)應(yīng)用程序,其中每個(gè)vhost服務(wù)一個(gè)應(yīng)用程序。
5.交換機(jī)類(lèi)型
1.direct Exchange(直接交換機(jī))
匹配路由鍵,只有完全匹配消息才會(huì)被轉(zhuǎn)發(fā)
2.Fanout Excange(扇出交換機(jī))
將消息發(fā)送至所有的隊(duì)列
3.Topic Exchange(主題交換機(jī))
將路由按模式匹配,此時(shí)隊(duì)列需要綁定要一個(gè)模式上。符號(hào)“#”匹配一個(gè)或多個(gè)詞,符號(hào)“匹配不多不少一個(gè)詞。因此“abc.#”能夠匹配到“abc.def.ghi”,但是“abc.” 只會(huì)匹配到“abc.def”。
4.Header Exchange
在綁定Exchange和Queue的時(shí)候指定一組鍵值對(duì),header為鍵,根據(jù)請(qǐng)求消息中攜帶的header進(jìn)行路由
6.工作模式
1.simple (簡(jiǎn)單模式)
一個(gè)消費(fèi)者消費(fèi)一個(gè)生產(chǎn)者生產(chǎn)的信息
2.Work queues(工作模式)
一個(gè)生產(chǎn)者生產(chǎn)信息,多個(gè)消費(fèi)者進(jìn)行消費(fèi),但是一條消息只能消費(fèi)一次
3.Publish/Subscribe(發(fā)布訂閱模式)
生產(chǎn)者首先投遞消息到交換機(jī),訂閱了這個(gè)交換機(jī)的隊(duì)列就會(huì)收到生產(chǎn)者投遞的消息
4.Routing(路由模式)
生產(chǎn)者生產(chǎn)消息投遞到direct交換機(jī)中,扇出交換機(jī)會(huì)根據(jù)消息攜帶的routing Key匹配相應(yīng)的隊(duì)列
5.Topics(主題模式)
生產(chǎn)者生產(chǎn)消息投遞到topic交換機(jī)中,上面是完全匹配路由鍵,而主題模式是模糊匹配,只要有合適規(guī)則的路由就會(huì)投遞給消費(fèi)者
7.保證消息的穩(wěn)定性
1.消息持久化
RabbitMQ的消息默認(rèn)存在內(nèi)存中的,一旦服務(wù)器意外掛掉,消息就會(huì)丟失
消息持久化需做到三點(diǎn)
- Exchange設(shè)置持久化
- Queue設(shè)置持久化
- Message持久化發(fā)送:發(fā)送消息設(shè)置發(fā)送模式deliveryMode=2,代表持久化消息
2.ACK確認(rèn)機(jī)制
多個(gè)消費(fèi)者同時(shí)收取消息,收取消息到一半,突然某個(gè)消費(fèi)者掛掉,要保證此條消息不丟失,就需要acknowledgement機(jī)制,就是消費(fèi)者消費(fèi)完要通知服務(wù)端,服務(wù)端才將數(shù)據(jù)刪除
這樣就解決了,及時(shí)一個(gè)消費(fèi)者出了問(wèn)題,沒(méi)有同步消息給服務(wù)端,還有其他的消費(fèi)端去消費(fèi),保證了消息不丟的case。
3.設(shè)置集群鏡像模式
我們先來(lái)介紹下RabbitMQ三種部署模式:
1)單節(jié)點(diǎn)模式:最簡(jiǎn)單的情況,非集群模式,節(jié)點(diǎn)掛了,消息就不能用了。業(yè)務(wù)可能癱瘓,只能等待。
2)普通模式:默認(rèn)的集群模式,某個(gè)節(jié)點(diǎn)掛了,該節(jié)點(diǎn)上的消息不能用,有影響的業(yè)務(wù)癱瘓,只能等待節(jié)點(diǎn)恢復(fù)重啟可用(必須持久化消息情況下)。
3)鏡像模式:把需要的隊(duì)列做成鏡像隊(duì)列,存在于多個(gè)節(jié)點(diǎn),屬于RabbitMQ的HA方案
為什么設(shè)置鏡像模式集群,因?yàn)殛?duì)列的內(nèi)容僅僅存在某一個(gè)節(jié)點(diǎn)上面,不會(huì)存在所有節(jié)點(diǎn)上面,所有節(jié)點(diǎn)僅僅存放消息結(jié)構(gòu)和元數(shù)據(jù)。下面自己畫(huà)了一張圖介紹普通集群丟失消息情況
4.消息補(bǔ)償機(jī)制
持久化的消息,保存到硬盤(pán)過(guò)程中,當(dāng)前隊(duì)列節(jié)點(diǎn)掛了,存儲(chǔ)節(jié)點(diǎn)硬盤(pán)又壞了,消息丟了,怎么辦?
產(chǎn)線網(wǎng)絡(luò)環(huán)境太復(fù)雜,所以不知數(shù)太多,消息補(bǔ)償機(jī)制需要建立在消息要寫(xiě)入DB日志,發(fā)送日志,接受日志,兩者的狀態(tài)必須記錄。
然后根據(jù)DB日志記錄check 消息發(fā)送消費(fèi)是否成功,不成功,進(jìn)行消息補(bǔ)償措施,重新發(fā)送消息處理。
8.如何實(shí)現(xiàn)延遲隊(duì)列
RabbitMQ本身沒(méi)有延遲隊(duì)列,需要靠TTL和DLX模擬出延遲的效果
TTL(Time To Live)
RabbitMQ可以針對(duì)Queue和Message設(shè)置 x-message-tt,來(lái)控制消息的生存時(shí)間,如果超時(shí),則消息變?yōu)閐ead letter
RabbitMQ針對(duì)隊(duì)列中的消息過(guò)期時(shí)間有兩種方法可以設(shè)置。
A: 通過(guò)隊(duì)列屬性設(shè)置,隊(duì)列中所有消息都有相同的過(guò)期時(shí)間。
B: 對(duì)消息進(jìn)行單獨(dú)設(shè)置,每條消息TTL可以不同。
如果同時(shí)使用,則消息的過(guò)期時(shí)間以?xún)烧咧gTTL較小的那個(gè)數(shù)值為準(zhǔn)。消息在隊(duì)列的生存時(shí)間一旦超過(guò)設(shè)置的TTL值,就成為dead letter
DLX (Dead-Letter-Exchange)
RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可選)兩個(gè)參數(shù),如果隊(duì)列內(nèi)出現(xiàn)了dead letter,則按照這兩個(gè)參數(shù)重新路由。
x-dead-letter-exchange:出現(xiàn)dead letter之后將dead letter重新發(fā)送到指定exchange
x-dead-letter-routing-key:指定routing-key發(fā)送
隊(duì)列出現(xiàn)dead letter的情況有:
消息或者隊(duì)列的TTL過(guò)期
隊(duì)列達(dá)到最大長(zhǎng)度
消息被消費(fèi)端拒絕(basic.reject or basic.nack)并且requeue=false
利用DLX,當(dāng)消息在一個(gè)隊(duì)列中變成死信后,它能被重新publish到另一個(gè)Exchange。這時(shí)候消息就可以重新被消費(fèi)。