株洲網(wǎng)站開(kāi)發(fā)2023年8月疫情又開(kāi)始了嗎
目錄
1.你們項(xiàng)目中哪里用到了RabbitMQ
2、為什么會(huì)選擇使用RabbitMQ
3、使用RabbitMQ如何保證消息不丟失
4、消息的重復(fù)消費(fèi)問(wèn)題如何解決的
5、如何解決消息堆積在MQ的問(wèn)題
6、RabbitMQ如何保證消費(fèi)的順序性
7、RabbitMQ的延遲隊(duì)列有了解過(guò)嘛
8、RabbitMQ如何設(shè)置消息過(guò)期
9、什么是死信交換機(jī)
10、RabbitMQ的集群有哪些
1.你們項(xiàng)目中哪里用到了RabbitMQ
RabbitMQ是我們項(xiàng)目中服務(wù)通信的主要方式之一 , 我們項(xiàng)目中服務(wù)通信主要有二種方式實(shí)現(xiàn) :
通過(guò)Feign實(shí)現(xiàn)服務(wù)的同步調(diào)用
通過(guò)MQ實(shí)現(xiàn)服務(wù)的異步通信
下面要結(jié)合自己的項(xiàng)目中功能來(lái)說(shuō)兩個(gè)地方
-
xxx
-
xxx
2、為什么會(huì)選擇使用RabbitMQ
我們項(xiàng)目中之所以選擇使用RabbitMQ,是因?yàn)樗墓δ鼙容^豐富 , 支持各種消息收發(fā)模式, 支持延遲隊(duì)列 , 惰性隊(duì)列
而且天然支持集群, 保證服務(wù)的高可用, 同時(shí)性能非常不錯(cuò) , 社區(qū)也比較活躍, 文檔資料非常豐富
使用MQ有很多好處,簡(jiǎn)單跟您說(shuō)幾個(gè):
吞吐量提升:無(wú)需等待訂閱者處理完成,響應(yīng)更快速
故障隔離:服務(wù)沒(méi)有直接調(diào)用,不存在級(jí)聯(lián)失敗問(wèn)題
調(diào)用間沒(méi)有阻塞,不會(huì)造成無(wú)效的資源占用
耦合度極低,每個(gè)服務(wù)都可以靈活插拔,可替換
流量削峰:不管發(fā)布事件的流量波動(dòng)多大,都由Broker接收,訂閱者可以按照自己的速度去處理事件
當(dāng)然使用使用MQ也有一些缺點(diǎn)
架構(gòu)復(fù)雜了,業(yè)務(wù)沒(méi)有明顯的流程線,不好管理
需要依賴(lài)于Broker的可靠、安全、性能
總之,瑕不掩瑜,使用了RabbitMQ之后可以大大提供程序的效率
3、使用RabbitMQ如何保證消息不丟失
消息從生產(chǎn)者發(fā)送到消費(fèi)者接收,會(huì)經(jīng)歷多個(gè)過(guò)程 , 其中的每一步都可能導(dǎo)致消息丟失
大體可以分為這樣幾種情況:
消息發(fā)送到交換機(jī)丟失
消息從交換機(jī)路由到隊(duì)列丟失
消息保存到隊(duì)列中丟失
消費(fèi)者消費(fèi)消息丟失
針對(duì)每一步,RabbitMQ分別給出了解決方案:
消息發(fā)送到交換機(jī)丟失:發(fā)布者確認(rèn)機(jī)制
消息發(fā)送到交換機(jī)失敗會(huì)向生產(chǎn)者返回失敗原因,生產(chǎn)者通過(guò)回調(diào)接收發(fā)送結(jié)果,如果發(fā)送失敗,重新發(fā)送,或者記錄日志人工介入
消息從交換機(jī)路由到隊(duì)列丟失:發(fā)布者回執(zhí)機(jī)制
消息從交換機(jī)路由到隊(duì)列失敗會(huì)向生產(chǎn)者返回失敗原因 ,生產(chǎn)者通過(guò)回調(diào)接收回調(diào)結(jié)果,如果發(fā)送失敗,重新發(fā)送,或者記錄日志人工介入
消息保存到隊(duì)列中丟失:MQ持久化
RabbitMQ運(yùn)行開(kāi)啟交換機(jī)持久化、隊(duì)列持久化、消息持久化,以保證消息在傳輸過(guò)程中不會(huì)丟失
消費(fèi)者消費(fèi)消息丟失:消費(fèi)者確認(rèn)機(jī)制
消費(fèi)者確認(rèn)機(jī)制指的是只有消費(fèi)者一方確認(rèn)消息消費(fèi)成功了,mq才刪除消息,否則就會(huì)重新發(fā)送消息給消費(fèi)者
通過(guò)RabbitMQ本身所提供的機(jī)制基本上已經(jīng)可以保證消息不丟失, 但是因?yàn)橐恍┨厥獾脑蜻€是會(huì)發(fā)送消息丟失問(wèn)題 ,
例如 : 回調(diào)丟失 , 系統(tǒng)宕機(jī), 磁盤(pán)損壞等 , 這種概率很小 , 但是如果想規(guī)避這些問(wèn)題 , 進(jìn)一步提高消息發(fā)送的成功率, 也可以通過(guò)程序自己進(jìn)行控制
設(shè)計(jì)一個(gè)消息狀態(tài)表 , 主要包含 : 消息id , 消息內(nèi)容 , 交換機(jī) , 消息路由key , 發(fā)送時(shí)間, 簽收狀態(tài)等字段 , 發(fā)送方業(yè)務(wù)執(zhí)行完畢之后 , 向消息狀態(tài)表保存一條消息記錄, 消息狀態(tài)為未簽收 , 之后再向MQ發(fā)送消息 , 消費(fèi)方接收消息消費(fèi)完畢之后 , 向發(fā)送方發(fā)送一條簽收消息 , 發(fā)送方接收到簽收消息之后 , 修改消息狀態(tài)表中的消息狀態(tài)為已簽收 ! 之后通過(guò)定時(shí)任務(wù)掃描消息狀態(tài)表中這些未簽收的消息 , 重新發(fā)送消息, 直到成功為止 , 對(duì)于已經(jīng)完成消費(fèi)的消息定時(shí)清理即可 !
4、消息的重復(fù)消費(fèi)問(wèn)題如何解決的
在使用RabbitMQ進(jìn)行消息收發(fā)的時(shí)候,如果發(fā)送失敗或者消費(fèi)失敗會(huì)自動(dòng)進(jìn)行重試,那么就有可能會(huì)導(dǎo)致消息的重復(fù)消費(fèi)
解決方案:
每條消息設(shè)置一個(gè)唯一的標(biāo)識(shí)id
冪等方案
token+redis
分布式鎖
數(shù)據(jù)庫(kù)鎖(悲觀鎖、樂(lè)觀鎖)
5、如何解決消息堆積在MQ的問(wèn)題
解決消息堆積有幾種種思路:
提高消費(fèi)者的消費(fèi)能力,例如使用多線程消費(fèi)
增加消費(fèi)者數(shù)量,提高消費(fèi)速度,可以使用ork隊(duì)列模式,設(shè)置多個(gè)消費(fèi)者消費(fèi)消費(fèi)同一個(gè)隊(duì)列中的消息
擴(kuò)大隊(duì)列容積,提高堆積上限
使用RabbitMQ惰性隊(duì)列,接收到消息后直接存入磁盤(pán)而非內(nèi)存,消費(fèi)者要消費(fèi)消息時(shí)才會(huì)從磁盤(pán)中讀取并加載到內(nèi)存
6、RabbitMQ如何保證消費(fèi)的順序性
一個(gè)隊(duì)列只設(shè)置一個(gè)消費(fèi)者消費(fèi)即可 , 多個(gè)消費(fèi)者之間是無(wú)法保證消息消費(fèi)順序性的
7、RabbitMQ的延遲隊(duì)列有了解過(guò)嘛
RabbitMQ的延遲隊(duì)列有兩種實(shí)現(xiàn)方案 :
使用消息過(guò)期TTL + 死信交換機(jī)
使用延遲交換機(jī)插件
8、RabbitMQ如何設(shè)置消息過(guò)期
RabbitMQ設(shè)置消息過(guò)期的方式有兩種 :
在隊(duì)列上設(shè)置過(guò)期時(shí)間,所有進(jìn)到這個(gè)隊(duì)列的消息就會(huì)具有統(tǒng)一的過(guò)期時(shí)間
為消息單獨(dú)設(shè)置過(guò)期時(shí)間
注意 :
隊(duì)列過(guò)期和消息過(guò)期同時(shí)存在 , 會(huì)以時(shí)間短的時(shí)間為準(zhǔn)
RabbitMQ隊(duì)列消息過(guò)期的機(jī)制是判斷隊(duì)列頭部元素是否過(guò)期 , 如果隊(duì)里頭部消息沒(méi)有到過(guò)期時(shí)間 , 中間消息到了過(guò)期時(shí)間, 這個(gè)消息也不會(huì)被自動(dòng)剔除
9、什么是死信交換機(jī)
死信交換機(jī)和正常的交換機(jī)沒(méi)有什么不同,當(dāng)一個(gè)包含死信
的隊(duì)列使用dead-letter-exchange
屬性,指定了一個(gè)交換機(jī),這個(gè)交換機(jī)稱(chēng)為死信交換機(jī)
也就是說(shuō)只有隊(duì)列中的死信才會(huì)流轉(zhuǎn)到死信交換機(jī),而當(dāng)一個(gè)隊(duì)列中的消息滿(mǎn)足下列情況之一時(shí),就會(huì)成為死信:
消費(fèi)者使用basic.reject或 basic.nack聲明消費(fèi)失敗,并且消息的requeue參數(shù)設(shè)置為false
消息是一個(gè)過(guò)期消息,超時(shí)無(wú)人消費(fèi)
要投遞的隊(duì)列消息滿(mǎn)了,無(wú)法投遞
一般的死信交換機(jī)還會(huì)再跟著一個(gè)專(zhuān)門(mén)的隊(duì)列,用來(lái)專(zhuān)門(mén)存儲(chǔ)所有的死信,以方便后期的人工干預(yù)
10、RabbitMQ的集群有哪些
RabbitMQ天然支持集群模式,它的集群有兩種模式:
普通集群:是一種分布式集群,將隊(duì)列分散到集群的各個(gè)節(jié)點(diǎn),從而提高整個(gè)集群的并發(fā)能力
這種集群會(huì)在集群的各個(gè)節(jié)點(diǎn)間共享部分?jǐn)?shù)據(jù),包括:交換機(jī)、隊(duì)列元信息。不包含隊(duì)列中的消息。
當(dāng)訪問(wèn)集群某節(jié)點(diǎn)時(shí),如果隊(duì)列不在該節(jié)點(diǎn),會(huì)從數(shù)據(jù)所在節(jié)點(diǎn)傳遞到當(dāng)前節(jié)點(diǎn)并返回
如果隊(duì)列所在節(jié)點(diǎn)宕機(jī),隊(duì)列中的消息就會(huì)丟失
鏡像集群:是一種主從集群,普通集群的基礎(chǔ)上,添加了主從備份功能,提高集群的數(shù)據(jù)可用性。
這種集群模式下,交換機(jī)、隊(duì)列、隊(duì)列中的消息會(huì)在各個(gè)mq的鏡像節(jié)點(diǎn)之間同步備份
創(chuàng)建隊(duì)列的節(jié)點(diǎn)被稱(chēng)為該隊(duì)列的主節(jié)點(diǎn),備份到的其它節(jié)點(diǎn)叫做該隊(duì)列的鏡像節(jié)點(diǎn)。
一個(gè)隊(duì)列的主節(jié)點(diǎn)可能是另一個(gè)隊(duì)列的鏡像節(jié)點(diǎn)
所有操作都是主節(jié)點(diǎn)完成,然后同步給鏡像節(jié)點(diǎn)
主宕機(jī)后,鏡像節(jié)點(diǎn)會(huì)替代成新的主機(jī)