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