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