柚子快報(bào)邀請(qǐng)碼778899分享:中間件-消息隊(duì)列
柚子快報(bào)邀請(qǐng)碼778899分享:中間件-消息隊(duì)列
消息隊(duì)列基礎(chǔ)知識(shí)
什么是消息隊(duì)列
本處提到的消息隊(duì)列是指各個(gè)服務(wù)以及系統(tǒng)組件/模塊之間的通信,屬于一種中間件。參與消息傳遞的雙方稱為生產(chǎn)者和消費(fèi)者,生產(chǎn)者負(fù)責(zé)發(fā)送消息,消費(fèi)者負(fù)責(zé)處理消息。
消息隊(duì)列作用
通過(guò)異步處理,提高系統(tǒng)性能(減少響應(yīng)所需時(shí)間)削峰/限流降低系統(tǒng)耦合性
消息隊(duì)列如何降低耦合性
消息隊(duì)列使用發(fā)布-訂閱模式工作,消息發(fā)送者(生產(chǎn)者)發(fā)布消息,一個(gè)或多個(gè)消息接受者(消費(fèi)者)訂閱消息。 從上圖可以看到消息發(fā)送者(生產(chǎn)者)和消息接受者(消費(fèi)者)之間沒(méi)有直接耦合,消息發(fā)送者將消息發(fā)送至分布式消息隊(duì)列即結(jié)束對(duì)消息的處理,消息接受者從分布式消息隊(duì)列獲取該消息后進(jìn)行后續(xù)處理,并不需要知道該消息從何而來(lái)。對(duì)新增業(yè)務(wù),只要對(duì)該類(lèi)消息感興趣,即可訂閱該消息,對(duì)原有系統(tǒng)和業(yè)務(wù)沒(méi)有任何影響,從而實(shí)現(xiàn)網(wǎng)站業(yè)務(wù)的可擴(kuò)展性設(shè)計(jì)。
消息隊(duì)列帶來(lái)的問(wèn)題
系統(tǒng)可用性下降系統(tǒng)復(fù)雜度提高一致性問(wèn)題
JMS Java消息服務(wù)
JMS(JAVA Message Service)API是一個(gè)消息服務(wù)的標(biāo)準(zhǔn)或者說(shuō)是規(guī)范,允許應(yīng)用程序組件基于JavaEE平臺(tái)創(chuàng)建、發(fā)送、接收和讀取消息。
JMS的兩種消息模型
點(diǎn)到點(diǎn)(P2P)模型 使用隊(duì)列(Queue)作為消息通信載體;滿足生產(chǎn)者與消費(fèi)者模式,一條消息只能被一個(gè)消費(fèi)者使用,未被消費(fèi)的消息在隊(duì)列中保留直到被消費(fèi)或超時(shí)。 發(fā)布/訂閱(Pub/Sub)模型 使用主題(Topic)作為消息通信載體,類(lèi)似于廣播模式;發(fā)布者發(fā)布一條消息,該消息通過(guò)主題傳遞給所有的訂閱者。
RPC與消息隊(duì)列區(qū)別
用途:RPC是用于解決兩個(gè)服務(wù)之間的遠(yuǎn)程通信問(wèn)題,用于調(diào)用遠(yuǎn)程計(jì)算機(jī)上某個(gè)服務(wù)的方法;消息隊(duì)列主要用來(lái)降低系統(tǒng)耦合性、實(shí)現(xiàn)任務(wù)異步、進(jìn)行流量削峰。通信方式:RPC是雙向直接網(wǎng)絡(luò)通訊,消息隊(duì)列是單向引入中間載體的網(wǎng)絡(luò)通訊。架構(gòu):消息隊(duì)列是需要把消息存儲(chǔ)起來(lái),RPC則沒(méi)有相關(guān)需求。請(qǐng)求處理的時(shí)效性:通過(guò)RPC發(fā)出的調(diào)配用一般會(huì)被處理,放在消息隊(duì)列中的消息不一定會(huì)被處理。
RabbitMQ
RabbitMQ 如何保證信息不丟失
開(kāi)啟生產(chǎn)者確認(rèn)機(jī)制,確保生產(chǎn)者的消息能到達(dá)隊(duì)列開(kāi)啟持久化功能,確保消息未消費(fèi)前在隊(duì)列中不會(huì)丟失開(kāi)啟消費(fèi)者確認(rèn)機(jī)制為auto,由spring確認(rèn)消息處理成功后完成ack開(kāi)啟消費(fèi)者失敗重試機(jī)制,多次失敗后將消息投遞到異常交換機(jī),交由人工處理
RabbitMQ消息重復(fù)消費(fèi)問(wèn)題怎么解決
設(shè)置一個(gè)唯一的標(biāo)識(shí)符,處理消息時(shí),先到數(shù)據(jù)庫(kù)查詢一下,如果不存在就正常處理,如果存在就不用再消費(fèi)冪等方案:利用redis分布式鎖、數(shù)據(jù)庫(kù)的鎖等
RabbitMQ中的死信交換機(jī)?(RabbitMQ延遲隊(duì)列了解過(guò)嗎?)
當(dāng)一個(gè)消息在一個(gè)隊(duì)列中變?yōu)樗佬藕螅梢员恢匦掳l(fā)送到另一個(gè)交換機(jī)中,這個(gè)交換機(jī)就是死信交換機(jī)。導(dǎo)致死信的幾種原因有:
消息被拒(Basic.Reject / Basic.Nack)且requeue = false消息TTL過(guò)期隊(duì)列滿了,無(wú)法再添加。
什么是延遲隊(duì)列?RabbitMQ如何實(shí)現(xiàn)延遲隊(duì)列?
延遲隊(duì)列指的是存儲(chǔ)對(duì)應(yīng)的延遲消息,消息被發(fā)送以后,并不想讓消費(fèi)者立刻拿到消息,而是等待特定時(shí)間后,消費(fèi)者才能拿到這個(gè)消息進(jìn)行消費(fèi)。 實(shí)現(xiàn)方式:
利用RabbitMQ的死信交換機(jī)和消息存活時(shí)間TTL來(lái)實(shí)現(xiàn)安裝死信插件(具體沒(méi)用過(guò))
RabbitMQ如果有100萬(wàn)消息堆積在MQ中,如何解決(消息堆積怎么解決)?
當(dāng)生產(chǎn)者發(fā)送消息的速度超過(guò)了消費(fèi)者處理消息的速度,就會(huì)導(dǎo)致隊(duì)列中的消息堆積,直到存儲(chǔ)消息達(dá)到上限。之后發(fā)送的消息就會(huì)變?yōu)樗佬牛蠒?huì)被拋棄,這就是消息堆積。
解決消息堆積有三種思路
增加更多消費(fèi)者消費(fèi)者使用線程池,多線程處理消息使用惰性隊(duì)列,擴(kuò)大堆積上線
惰性隊(duì)列
在聲明隊(duì)列的時(shí)候設(shè)置屬性x-queue-mode為lazy,即惰性隊(duì)列基于磁盤(pán)存儲(chǔ),消息上限高性能比較穩(wěn)定,但基于磁盤(pán)存儲(chǔ),受限于磁盤(pán)IO,時(shí)效性會(huì)降低。
RabbitMQ的高可用機(jī)制
在生產(chǎn)環(huán)境中,使用集群來(lái)保證高可用性
普通集群
又稱標(biāo)準(zhǔn)集群,具備以下特征:
會(huì)在集群的各個(gè)節(jié)點(diǎn)減共享部分?jǐn)?shù)據(jù),包括:交換機(jī)、隊(duì)列元信息。不包含隊(duì)列中的信息。當(dāng)訪問(wèn)集群某個(gè)節(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ì)消失
鏡像集群
本質(zhì)是主從模式,具備下面的特征
交換機(jī)、隊(duì)列、隊(duì)列中的消息 會(huì)在各個(gè)mq的鏡像節(jié)點(diǎn)之間同步備份創(chuàng)建隊(duì)列的節(jié)點(diǎn)被稱為該隊(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)主節(jié)點(diǎn)宕機(jī)后,鏡像節(jié)點(diǎn)會(huì)替代成為新的主節(jié)點(diǎn)
仲裁隊(duì)列
與鏡像隊(duì)列一樣,都是主從模式,支持主從數(shù)據(jù)同步使用簡(jiǎn)單,沒(méi)有復(fù)雜配置,只需在聲明隊(duì)列的時(shí)候指定使用仲裁隊(duì)列主從同步基于Raft協(xié)議,強(qiáng)一致性
Kafka
Kafka如何保證消息不丟失
生產(chǎn)者發(fā)送消息到Brocker丟失
設(shè)置異步發(fā)送
消息在Brocker丟失
Kafka如何保證消費(fèi)順序性
kafka默認(rèn)存儲(chǔ)和消費(fèi)信息,是不能保證順序性的。因?yàn)橐粋€(gè)topic數(shù)據(jù)可能存儲(chǔ)在不同的分區(qū)中,每個(gè)分區(qū)都有一個(gè)按照順序存儲(chǔ)的偏移量。如果消費(fèi)者關(guān)聯(lián)了多個(gè)分區(qū),不能保證順序性。 但是通過(guò)把消息存儲(chǔ)到一個(gè)分區(qū)下可以解決。方法有兩種:1)發(fā)送消息時(shí)指定分區(qū)號(hào)。2)發(fā)送消息時(shí),按照相同的業(yè)務(wù)設(shè)置相同的key。因?yàn)槟J(rèn)情況下,分區(qū)也是通過(guò)key的hashcode值來(lái)選擇分區(qū)的。hash值如果一樣的話,分區(qū)一定一樣。
柚子快報(bào)邀請(qǐng)碼778899分享:中間件-消息隊(duì)列
文章鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。