RabbitMQ 簡介
什么是MQ褐筛?
MQ全稱為Message Queue,即消息隊列。是一種用于在分布式系統(tǒng)中傳遞消息的中間件。它通過在生產(chǎn)者和消費者之間引入一個中間層——消息隊列惋鸥,來解耦兩者,使得它們可以獨立地生產(chǎn)和消費消息悍缠。MQ 可以有效地解決系統(tǒng)之間的異步通信卦绣、流量削峰填谷和數(shù)據(jù)解耦等問題,是現(xiàn)代分布式系統(tǒng)和微服務(wù)架構(gòu)中的重要組成部分飞蚓。
典型的模式
生產(chǎn)者滤港、消費者模型。
這種模式MQ本身就相當(dāng)于一個中間件玷坠,用于生產(chǎn)方通過MQ與消費方之間的交互作用蜗搔。
AMQP 協(xié)議
AMQP,即Advanced Message Queuing Protocol (高級消息隊列協(xié)議)八堡,一個提供統(tǒng)一消息服務(wù)的應(yīng)用層標(biāo)準高級消息隊列協(xié)議樟凄,是應(yīng)用層協(xié)議的一個開放標(biāo)準,為面向消息的中間件設(shè)計兄渺》炝洌基于此協(xié)議的客戶端與消息中間件可傳遞消息,并不受客戶端/中間件不同產(chǎn)品挂谍,不同的開發(fā)語言等條件的限制叔壤。Erlang中的實現(xiàn)有RabbitMQ等。2006年口叙,AMQP 規(guī)范發(fā)布炼绘。
主要特性
1.高性能:采用高效的消息傳遞引擎,能夠處理大量的并發(fā)消息妄田,適用于高吞吐量的應(yīng)用場景俺亮。
2.可擴展性:支持分布式部署驮捍,通過集群和分片技術(shù),可以輕松擴展系統(tǒng)容量脚曾,適應(yīng)業(yè)務(wù)的快速增長东且。
3.高可用性:通過主備切換、數(shù)據(jù)冗余和故障轉(zhuǎn)移機制本讥,確保系統(tǒng)的高可用性和數(shù)據(jù)的可靠性珊泳。
4.多協(xié)議支持:支持多種消息協(xié)議(如 AMQP、MQTT拷沸、STOMP)色查,方便不同類型的應(yīng)用集成。
5.靈活的消息路由:支持多種消息路由模式(如直連堵漱、廣播综慎、主題),滿足不同業(yè)務(wù)場景的需求勤庐。
6.消息持久化:提供強大的消息持久化功能示惊,確保消息在系統(tǒng)崩潰或重啟時不會丟失。
7.安全性:支持多種安全機制(如身份認證愉镰、權(quán)限控制米罚、數(shù)據(jù)加密),保障消息傳遞的安全性丈探。
8.監(jiān)控與管理:提供豐富的監(jiān)控和管理工具录择,方便運維人員實時監(jiān)控系統(tǒng)狀態(tài)和性能指標(biāo)。
模式
存儲轉(zhuǎn)發(fā)(多個消息發(fā)送者碗降,單個消息接收者)
分布式事務(wù)(多個消息發(fā)送者隘竭,多個消息接收者)
發(fā)布訂閱(多個消息發(fā)送者,多個消息接收者)
基于內(nèi)容的路由(多個消息發(fā)送者讼渊,多個消息接收者)
文件傳輸隊列(多個消息發(fā)送者动看,多個消息接收者)
點對點連接(單個消息發(fā)送者,單個消息接收者)
RabbitMQ
RabbitMQ 是一個開源的消息代理軟件爪幻,最初由 Pivotal Software 開發(fā)菱皆,現(xiàn)為 VMware 旗下。RabbitMQ 實現(xiàn)了高級消息隊列協(xié)議(AMQP),并且支持多種消息協(xié)議(如 MQTT、STOMP)扬绪。它廣泛應(yīng)用于分布式系統(tǒng)和微服務(wù)架構(gòu)中,提供高性能篷店、可靠的消息傳遞服務(wù)。
主要特性
1.多協(xié)議支持:支持 AMQP臭家、MQTT船庇、STOMP 等多種消息協(xié)議吭产。
2.豐富的消息路由功能:支持直連交換機(Direct Exchange)侣监、扇出交換機(Fanout Exchange)鸭轮、主題交換機(Topic Exchange)和頭交換機(Headers Exchange)。
3.消息持久化:支持將消息持久化到磁盤橄霉,確保消息在 RabbitMQ 崩潰或重啟時不會丟失窃爷。
4.高可用性:通過集群和鏡像隊列提供高可用性和故障轉(zhuǎn)移功能。
5.插件系統(tǒng):支持多種插件姓蜂,如管理插件按厘、監(jiān)控插件和安全插件。
6.管理和監(jiān)控:提供 Web 界面和命令行工具钱慢,方便用戶進行管理和監(jiān)控逮京。
RabbitMQ作用和場景
1. 微服務(wù)架構(gòu)中的解耦
在微服務(wù)架構(gòu)中,服務(wù)之間的直接調(diào)用會導(dǎo)致強耦合束莫,難以維護和擴展懒棉。通過引入消息隊列,服務(wù)之間可以進行異步通信览绿,從而實現(xiàn)解耦策严。
- 示例:
訂單處理系統(tǒng):訂單服務(wù)生成訂單后,將訂單信息發(fā)送到消息隊列饿敲。支付服務(wù)從消息隊列中讀取訂單信息并進行支付處理妻导,支付成功后再將支付結(jié)果發(fā)送到消息隊列,由訂單服務(wù)更新訂單狀態(tài)怀各。
2. 流量削峰填谷
在高并發(fā)場景中倔韭,系統(tǒng)瞬時流量可能會非常高,導(dǎo)致系統(tǒng)負載過大瓢对。消息隊列可以緩沖高峰期的請求寿酌,平滑系統(tǒng)負載,防止系統(tǒng)崩潰沥曹。
- 示例:
秒殺系統(tǒng):在秒殺活動中份名,用戶請求量會在短時間內(nèi)激增。通過消息隊列妓美,系統(tǒng)可以將用戶請求排隊僵腺,逐個處理,避免數(shù)據(jù)庫和應(yīng)用服務(wù)器的瞬時過載壶栋。
3. 異步處理
一些任務(wù)可能需要較長時間才能完成辰如,通過消息隊列可以將這些任務(wù)異步化,避免阻塞主流程贵试,提升系統(tǒng)響應(yīng)速度琉兜。
- 示例:
郵件通知:用戶注冊成功后凯正,系統(tǒng)需要發(fā)送歡迎郵件⊥泱可以將郵件發(fā)送任務(wù)放入消息隊列廊散,由專門的郵件服務(wù)異步處理,主流程無需等待郵件發(fā)送完成梧疲。
4. 日志收集
在分布式系統(tǒng)中允睹,日志收集和分析是非常重要的。消息隊列可以用于集中收集和傳輸日志幌氮,實現(xiàn)日志的統(tǒng)一管理和分析缭受。
- 示例:
日志系統(tǒng):各個服務(wù)將日志信息發(fā)送到消息隊列,日志處理服務(wù)從消息隊列中讀取日志信息该互,進行存儲和分析米者。
5. 事件驅(qū)動架構(gòu)
在事件驅(qū)動架構(gòu)中,系統(tǒng)通過事件來驅(qū)動業(yè)務(wù)流程宇智。消息隊列可以用于事件的發(fā)布和訂閱蔓搞,實現(xiàn)事件的分發(fā)和處理。
- 示例:
用戶行為跟蹤:用戶在網(wǎng)站上的操作(如點擊普筹、瀏覽败明、購買)會觸發(fā)事件,這些事件通過消息隊列傳遞給數(shù)據(jù)分析系統(tǒng)太防,進行實時分析和處理妻顶。
6. 數(shù)據(jù)同步
在多系統(tǒng)或多數(shù)據(jù)中心環(huán)境中,數(shù)據(jù)的一致性和同步是一個挑戰(zhàn)蜒车。消息隊列可以用于不同系統(tǒng)之間的數(shù)據(jù)同步讳嘱,確保數(shù)據(jù)的一致性。
- 示例:
數(shù)據(jù)庫同步:主數(shù)據(jù)庫的更新操作通過消息隊列傳遞給從數(shù)據(jù)庫酿愧,從數(shù)據(jù)庫根據(jù)消息進行數(shù)據(jù)更新沥潭,確保主從數(shù)據(jù)庫的一致性。
7. 任務(wù)調(diào)度
消息隊列可以用于任務(wù)的分發(fā)和調(diào)度嬉挡,協(xié)調(diào)多個工作節(jié)點的工作钝鸽,提高系統(tǒng)的并行處理能力。
- 示例:
分布式任務(wù)調(diào)度:任務(wù)生成系統(tǒng)將任務(wù)放入消息隊列庞钢,多個工作節(jié)點從消息隊列中讀取任務(wù)并進行處理拔恰,實現(xiàn)任務(wù)的并行調(diào)度和處理。
8. 事務(wù)處理
在分布式系統(tǒng)中基括,實現(xiàn)分布式事務(wù)是一個難題颜懊。通過消息隊列,可以實現(xiàn)最終一致性的事務(wù)處理。
- 示例:
訂單和庫存系統(tǒng):訂單服務(wù)生成訂單后河爹,將訂單信息發(fā)送到消息隊列匠璧,庫存服務(wù)從消息隊列中讀取訂單信息并更新庫存。通過消息隊列的確認機制咸这,確保訂單和庫存的一致性夷恍。
9. 緩存更新
在使用緩存時,當(dāng)數(shù)據(jù)發(fā)生變化時炊苫,需要更新緩存裁厅。消息隊列可以用于通知緩存系統(tǒng)更新緩存數(shù)據(jù)。
- 示例:
緩存更新通知:當(dāng)數(shù)據(jù)庫中的數(shù)據(jù)發(fā)生變化時侨艾,將更新信息發(fā)送到消息隊列,緩存系統(tǒng)從消息隊列中讀取更新信息并更新緩存拓挥。
10. 延遲任務(wù)
消息隊列可以用于實現(xiàn)延遲任務(wù)唠梨,即在指定時間后處理任務(wù)。
- 示例:
訂單超時取消:用戶下單后侥啤,如果在一定時間內(nèi)未完成支付当叭,系統(tǒng)自動取消訂單「蔷模可以將訂單信息放入消息隊列蚁鳖,設(shè)置延遲時間,延遲時間到后由系統(tǒng)自動取消訂單
RabbitMQ的缺點
1.系統(tǒng)可用性降低:由于引入了外部依賴赁炎,系統(tǒng)的穩(wěn)定性會變差醉箕。一旦RabbitMQ宕機,可能會對業(yè)務(wù)產(chǎn)生影響徙垫。
2.系統(tǒng)復(fù)雜度提高:引入RabbitMQ后讥裤,系統(tǒng)的復(fù)雜度會大大提高。原本的服務(wù)之間同步的服務(wù)調(diào)用會變成異步調(diào)用姻报,數(shù)據(jù)鏈路會變得更復(fù)雜己英,并且還會帶來一系列問題。
3.消息一致性問題:在多系統(tǒng)之間進行消息傳遞時吴旋,需要考慮消息的一致性問題损肛。例如,如果B系統(tǒng)成功處理了消息而C系統(tǒng)失敗荣瑟,需要有一種機制來處理這種情況以保持消息的一致性治拿。
4.數(shù)據(jù)丟失風(fēng)險:如果使用不可靠的網(wǎng)絡(luò)或者不恰當(dāng)?shù)呐渲茫赡軙?dǎo)致消息在傳輸過程中丟失褂傀。
5.性能瓶頸:雖然RabbitMQ支持水平擴展忍啤,但如果生產(chǎn)者和消費者的處理能力不匹配,可能會導(dǎo)致消息積壓和性能問題。
6.學(xué)習(xí)曲線陡峭:對于初學(xué)者來說同波,RabbitMQ的概念和用法可能比較復(fù)雜鳄梅,需要花費一定的時間和精力來學(xué)習(xí)和掌握。
7.安全性問題:雖然RabbitMQ提供了一些安全特性未檩,如用戶認證和訪問控制戴尸,但如果沒有正確配置或管理,可能會存在安全風(fēng)險冤狡。
RabbitMQ基本概念
基礎(chǔ)名詞
- Channel(信道):多路復(fù)?連接中的?條獨?的雙向數(shù)據(jù)流通道孙蒙。信道是建?在真實的TCP連接內(nèi)的虛擬連接,復(fù)?TCP連接的通道悲雳。
- Producer(消息的?產(chǎn)者):向消息隊列發(fā)布消息的客戶端應(yīng)?程序挎峦。
- Consumer(消息的消費者):從消息隊列取得消息的客戶端應(yīng)?程序。
- Message(消息):消息由消息頭和消息體組成合瓢。消息體是不透明的坦胶,?消息頭則由?系列的可選屬性組成,這些屬性包括routing-key(路由鍵)晴楔、priority(消息優(yōu)先權(quán))顿苇、delivery-mode(是否持久性存儲)等。
- Routing Key(路由鍵):消息頭的?個屬性税弃,?于標(biāo)記消息的路由規(guī)則纪岁,決定了交換機的轉(zhuǎn)發(fā)路徑。最?長度255 字節(jié)则果。
- Queue(消息隊列):存儲消息的?種數(shù)據(jù)結(jié)構(gòu)幔翰,?來保存消息,直到消息發(fā)送給消費者短条。它是消息的容器导匣,也是消息的終點。?個消息可投??個或多個隊列茸时。消息?直在隊列??贡定,等待消費者連接到這個隊列將消息取?。需要注意可都,當(dāng)多個消費者訂閱同?個Queue缓待,這時Queue中的消息會被平均分攤給多個消費者進?處理,?不是每個消費者都收到所有的消息并處理渠牲,每?條消息只能被?個訂閱者接收旋炒。
- 交換(交換路由器):提供生產(chǎn)者和隊列之間的匹配,接收生產(chǎn)者發(fā)送的消息签杈,并根據(jù)路由規(guī)則將這些消息轉(zhuǎn)發(fā)到消息隊列柱瘫镇。交換用于轉(zhuǎn)發(fā)消息鼎兽。它不會存儲消息。如果沒有綁定到exchange的隊列铣除,它將直接丟棄生產(chǎn)者發(fā)送的消息谚咬。交出交換機有四種消息調(diào)度策略(將在下一節(jié)中介紹),即扇出尚粘、直接择卦、主題和頭。
- Binding(綁定):?于建?Exchange和Queue之間的關(guān)聯(lián)郎嫁。?個綁定就是基于Binding Key將Exchange和Queue連接起來的路由規(guī)
則秉继,所以可以將交換器理解成?個由Binding構(gòu)成的路由表。 - Binding Key(綁定鍵):Exchange與Queue的綁定關(guān)系泽铛,?于匹配Routing Key尚辑。最?長度255 字節(jié)。
- Broker:RabbitMQ Server厚宰,服務(wù)器實體腌巾。
工作流程
生產(chǎn)者發(fā)送消息:生產(chǎn)者通過RabbitMQ的客戶端庫創(chuàng)建消息,并使用指定的交換機和路由鍵將消息發(fā)送到RabbitMQ服務(wù)器铲觉。
交換機接收并路由消息:交換機接收到生產(chǎn)者的消息后,根據(jù)配置的路由規(guī)則和路由鍵將消息分發(fā)到相應(yīng)的隊列中吓坚。
消費者消費消息:消費者連接到RabbitMQ服務(wù)器撵幽,并監(jiān)聽指定的隊列。當(dāng)隊列中有新消息時礁击,消費者從隊列中獲取并處理消息盐杂。處理完成后,消費者可以選擇發(fā)送確認消息給RabbitMQ服務(wù)器哆窿,以表示消息已被成功處理链烈。
在整個工作流程中,RabbitMQ服務(wù)器充當(dāng)了消息代理的角色挚躯,負責(zé)在生產(chǎn)者和消費者之間進行消息的傳遞和路由强衡。通過使用隊列、交換機和路由鍵等核心概念码荔,RabbitMQ實現(xiàn)了高效漩勤、可靠和靈活的消息傳遞機制。
需要注意的是缩搅,RabbitMQ還支持一些高級特性和擴展越败,如消息持久化、事務(wù)硼瓣、集群和鏡像隊列等究飞。這些特性和擴展可以進一步提高RabbitMQ的可用性、可靠性和擴展性。
消費模式
簡單消費模式
最直接的方式亿傅,P端發(fā)送一個消息到一個指定的queue媒峡,中間不需要任何exchange規(guī)則。C端按queue方式進行消費袱蜡。
在上圖的模型中丝蹭,有以下概念:
Producer:生產(chǎn)者,也就是要發(fā)送消息的程序
Consumer:消費者:消息的接受者坪蚁。
Queue:消息隊列奔穿,圖中紅色部分∶粑睿可以緩存消息贱田;生產(chǎn)者向其中投遞消息,消費者從其中取出消息嘴脾。
一個生產(chǎn)者男摧、一個消費者,不需要設(shè)置交換機(使用默認的交換機)译打。
工作隊列或者競爭消費者模式
與簡單模式相比耗拓,多了一個或一些消費端,多個消費端共同消費同一個隊列中的消息奏司。一個消息只會被一個消費者消費乔询。
一個生產(chǎn)者、多個消費者(競爭關(guān)系)韵洋,不需要設(shè)置交換機(使用默認的交換機)竿刁。
發(fā)布訂閱模式
在訂閱模型中,多了一個 Exchange 角色搪缨,而且過程略有變化:
Producer:生產(chǎn)者食拜,也就是要發(fā)送消息的程序,但是不再發(fā)送到隊列中副编,而是發(fā)給X(交換機)
Consumer:消費者负甸,消息的接收者
Queue:消息隊列,接收消息齿桃、緩存消息Exchange:交換機(X)惑惶。一方面,接收生產(chǎn)者發(fā)送的消息短纵。另一方面带污,知道如何處理消息,例如遞交給某個特別隊列香到、遞交給所有隊列鱼冀、或是將消息丟棄报破。到底如何操作,取決于Exchange的類型千绪。
Exchange(交換機)只負責(zé)轉(zhuǎn)發(fā)消息充易,不具備存儲消息的能力,因此如果沒有任何隊列與 Exchange 綁定荸型,或者沒有符合路由規(guī)則的隊列盹靴,那么消息會丟失!producer只負責(zé)發(fā)送消息瑞妇,至于消息進入哪個queue稿静,由exchange來分配。
發(fā)布訂閱模式與工作隊列模式的區(qū)別:
1.工作隊列模式不用定義交換機辕狰,而發(fā)布/訂閱模式需要定義交換機
2.發(fā)布/訂閱模式的生產(chǎn)方是面向交換機發(fā)送消息改备,工作隊列模式的生產(chǎn)方是面向隊列發(fā)送消息(底層使用默認交換機)
3.發(fā)布/訂閱模式需要設(shè)置隊列和交換機的綁定,工作隊列模式不需要設(shè)置蔓倍,實際上工作隊列模式會將隊列綁 定到默認的交換機
- 使用場景:
所有消費者獲得相同的消息悬钳,例如天氣預(yù)報。
Exchange有常見以下3種類型:
Fanout-發(fā)布訂閱模式(廣播)
Fanout:廣播偶翅,將消息交給所有綁定到交換機的隊列默勾,交換機需要與隊列進行綁定,綁定之后聚谁;一個消息可以被多個消費者都收到灾测。
在廣播模式下,消息發(fā)送流程是這樣的:
- 可以有多個消費者
- 每個消費者有自己的queue(隊列)
- 每個隊列都要綁定到Exchange(交換機)
- 生產(chǎn)者發(fā)送的消息垦巴,只能發(fā)送到交換機,交換機來決定要發(fā)給哪個隊列铭段,生產(chǎn)者無法決定骤宣。
- 交換機把消息發(fā)送給綁定過的所有隊列
- 隊列的消費者都能拿到消息。實現(xiàn)一條消息被多個消費者消費
Direct-發(fā)布訂閱模式(定向)
Direct:定向序愚,把消息交給符合指定routing key 的隊列
在定向模式下憔披,消息發(fā)送流程是這樣的:
1.有選擇性的接收消息
2.在廣播模式中,生產(chǎn)者發(fā)布消息爸吮,所有消費者都可以獲取所有消息芬膝。在定向模式中,我們將添加一個功能 - 我們將只能訂閱一部分消息形娇。
3.在定向模型下锰霜,隊列與交換機的綁定,不能是任意綁定了桐早,而是要指定一個RoutingKey(路由key)
4.消息的發(fā)送方在向Exchange發(fā)送消息時癣缅,也必須指定消息的routing key厨剪。
Topic-發(fā)布訂閱模式(通配符)
Topic:通配符,把消息交給符合routing pattern(路由模式) 的隊列
Topic類型與Direct相比友存,都是可以根據(jù)RoutingKey把消息路由到不同的隊列祷膳。只不過Topic類型Exchange可以讓隊列在綁定Routing key 的時候使用通配符
重點概念
事務(wù)
RabbitMQ 提供了事務(wù)機制來確保消息的可靠性傳遞。使用事務(wù)機制時屡立,可以在發(fā)送消息之前開啟一個事務(wù)直晨,在事務(wù)內(nèi)發(fā)送消息并進行確認提交,以確保消息被正確地發(fā)送到 RabbitMQ 中膨俐。
下面是使用 RabbitMQ 事務(wù)機制發(fā)送消息的一般步驟:
開啟事務(wù):通過 tx_select() 方法開啟一個事務(wù)勇皇。
發(fā)送消息:在事務(wù)內(nèi)使用 basic_publish() 方法發(fā)送消息到指定的 Exchange 和隊列。
提交事務(wù):通過 tx_commit() 方法提交事務(wù)吟策,確保在事務(wù)內(nèi)的操作生效儒士。
回滾事務(wù)(可選):如果發(fā)送消息過程中出現(xiàn)異常或錯誤檩坚,可以通過 tx_rollback() 方法回滾事務(wù)着撩,撤銷事務(wù)內(nèi)的操作。
事務(wù)機制會對性能產(chǎn)生一定的影響匾委,因為它需要進行額外的操作來維護事務(wù)的一致性拖叙。在高并發(fā)場景下,使用事務(wù)可能會導(dǎo)致性能下降赂乐。因此薯鳍,在選擇使用事務(wù)機制時,請根據(jù)實際需求和性能要求進行權(quán)衡挨措。
總的來說挖滤,事務(wù)機制提供了一種確保消息傳遞可靠性的方法,但在實際應(yīng)用中需要慎重考慮其對性能的影響浅役。在大部分情況下斩松,使用確認機制(Publisher Confirm)已經(jīng)能夠滿足消息傳遞的可靠性要求,并且對性能影響較小觉既。
消息確認機制(ACK)
RabbitMQ通過 publisher confirm 機制來實現(xiàn)的消息發(fā)送端確認惧盹。生產(chǎn)者將信道設(shè)置成confirm(確認)模式,一旦信道進入confirm 模式瞪讼,所有在該信道上?面發(fā)布的消息都會被指派一個唯一的ID(從 1 開始)钧椰,一旦消息被投遞到所有匹配的隊列之后 (如果消息和隊列是持久化的,那么確認消息會在消息持久化后發(fā)出)符欠,RabbitMQ 就會發(fā)送一個確認(Basic.Ack)給生產(chǎn)者(包含消息的唯一ID)嫡霞,這樣生產(chǎn)者就知道消息已經(jīng)正確送達了。
整個過程需要保證消費者背亥、RabbitMQ自己和消費者都不能丟消息秒际。
** RabbitMQ 消息確認機制分為兩大類**
- 消息發(fā)送確認悬赏,又分為:
生產(chǎn)者到交換機的確認;
交換機到隊列的確認娄徊。 - 消息接收確認闽颇。
消息發(fā)送確認
RabbitMQ 的消息發(fā)送確認有兩種實現(xiàn)方式:ConfirmCallback 方法、ReturnCallback 方法寄锐。
1)ConfirmCallback方法
ConfirmCallback 是一個回調(diào)接口兵多,用于確認消息否是到達交換機中。
2)ReturnCallback方法
ReturnCallback 也是一個回調(diào)接口橄仆,用于確認消息是否在交換機中路由到了隊列剩膘。
消息接收確認
消費者確認發(fā)生在 監(jiān)聽隊列的消費者處理業(yè)務(wù)失敗,如:發(fā)生了異常盆顾、不符合要求的數(shù)據(jù)等怠褐。這些場景就 需要我們手動處理消息,比如:重新發(fā)送消息或者丟棄消息您宪。
RabbitMQ 的 消息確認機制(ACK) 默認是自動確認的奈懒。自動確認會 在消息發(fā)送給消費者后立即確認,但 存在丟失消息的可能宪巨。如果消費端消費邏輯拋出了異常磷杏,假如我們使用了事務(wù)的回滾,也只是保證了數(shù)據(jù)的一致性捏卓,消息還是丟失了极祸。也就是消費端沒有處理成功這條消息,那么就相當(dāng)于丟失了消息怠晴。
消息的確認模式有三種:
- AcknowledgeMode.NONE:自動確認遥金。(默認)
- AcknowledgeMode.AUTO:根據(jù)情況確認。
- AcknowledgeMode.MANUAL:手動確認蒜田。(推薦)
消費者收到消息后汰规,手動調(diào)用 Channel 的 basicAck()/basicReject()/basicNack() 方法后,RabbitMQ 收到消息后物邑,才認為本次投遞完成。
- basicAck():用于確認當(dāng)前消息滔金。
- basicReject():用于拒絕當(dāng)前消息色解,可以自定義是否重回隊列。
- basicNack():用于批量拒絕消息(這是 AMPQ 0-9-1 的 RabbitMQ 擴展)餐茵。
持久性
持久化科阎,即將原本存在于內(nèi)存中的數(shù)據(jù)寫入到磁盤上永久保存數(shù)據(jù),防止服務(wù)宕機時內(nèi)存數(shù)據(jù)的丟失忿族。
RabbitMQ 的持久化
持久化是消息隊列系統(tǒng)中的一個重要特性锣笨,它確保消息在系統(tǒng)崩潰或重啟時不會丟失蝌矛。RabbitMQ 提供了多種持久化機制來保證消息的可靠性,包括隊列持久化错英、消息持久化和交換機持久化入撒。以下是對 RabbitMQ 持久化機制的詳細介紹。
隊列持久化
隊列持久化是指將隊列的元數(shù)據(jù)(如隊列名稱椭岩、屬性等)保存到磁盤中茅逮。持久化隊列在 RabbitMQ 重啟后仍然存在,能夠繼續(xù)接收和傳遞消息判哥。
聲明持久化隊列的示例:
import pika
# 創(chuàng)建連接和頻道
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# 聲明持久化隊列
channel.queue_declare(queue='persistent_queue', durable=True)
在上述代碼中献雅,通過設(shè)置 durable=True
參數(shù)來聲明一個持久化隊列。
消息持久化
消息持久化是指將消息內(nèi)容保存到磁盤中塌计。持久化消息在 RabbitMQ 重啟后仍然存在挺身,可以繼續(xù)傳遞給消費者。消息持久化需要生產(chǎn)者在發(fā)送消息時指定消息的持久化屬性锌仅。
發(fā)送持久化消息的示例:
import pika
# 創(chuàng)建連接和頻道
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# 聲明持久化隊列
channel.queue_declare(queue='persistent_queue', durable=True)
# 發(fā)送持久化消息
message = "Hello, Persistent World!"
channel.basic_publish(exchange='',
routing_key='persistent_queue',
body=message,
properties=pika.BasicProperties(delivery_mode=2)) # 設(shè)置消息持久化屬性
print(" [x] Sent 'Hello, Persistent World!'")
在上述代碼中章钾,通過設(shè)置 delivery_mode=2
參數(shù)來發(fā)送持久化消息。
交換機持久化
交換機持久化是指將交換機的元數(shù)據(jù)(如交換機名稱技扼、類型伍玖、屬性等)保存到磁盤中。持久化交換機在 RabbitMQ 重啟后仍然存在剿吻,能夠繼續(xù)接收和路由消息窍箍。
聲明持久化交換機的示例:
import pika
# 創(chuàng)建連接和頻道
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# 聲明持久化交換機
channel.exchange_declare(exchange='persistent_exchange', exchange_type='direct', durable=True)
在上述代碼中,通過設(shè)置 durable=True
參數(shù)來聲明一個持久化交換機丽旅。
持久化的注意事項
- 性能影響:持久化操作會增加磁盤 I/O椰棘,可能會影響 RabbitMQ 的性能。在高并發(fā)場景下榄笙,需要權(quán)衡持久化帶來的可靠性和性能之間的關(guān)系邪狞。
- 消息確認:為了確保消息被成功持久化,消費者需要發(fā)送消息確認(Acknowledgment)茅撞。RabbitMQ 在收到消息確認后才會將消息從隊列中移除帆卓。
- 鏡像隊列:在高可用性場景下,可以使用鏡像隊列(Mirrored Queue)來實現(xiàn)隊列的高可用米丘。鏡像隊列會將消息復(fù)制到多個節(jié)點剑令,確保在節(jié)點故障時消息不會丟失。
鏡像隊列的配置示例:
# 使用 RabbitMQ 管理插件配置鏡像隊列策略
rabbitmqctl set_policy ha-all "" '{"ha-mode":"all"}'
在上述命令中拄查,ha-all
是策略名稱吁津,""
是匹配模式,{"ha-mode":"all"}
是策略定義堕扶,表示將所有隊列配置為鏡像隊列碍脏。
總結(jié)
RabbitMQ 提供了多種持久化機制來確保消息的可靠性梭依,包括隊列持久化、消息持久化和交換機持久化典尾。通過合理配置持久化機制役拴,可以在系統(tǒng)崩潰或重啟時確保消息不丟失。然而急黎,持久化操作會增加磁盤 I/O扎狱,需要在可靠性和性能之間進行權(quán)衡。在高可用性場景下勃教,可以使用鏡像隊列來實現(xiàn)隊列的高可用淤击,進一步提升系統(tǒng)的可靠性。