本期分享呢草丧,知識經(jīng)驗上的分享,如果有些同學(xué)對于 MQ 還陌生的話莹桅,請先行去學(xué)習(xí)基礎(chǔ)篇昌执,這里是應(yīng)用經(jīng)驗上的分享,前提是 解耦、異步懂拾、消峰 你都知道的前提下闡述的煤禽。
1、MQ 集群架構(gòu)圖
NameServer岖赋、Broker呜师、Producer、Consumer之間如何進(jìn)行通信贾节,如何工作:
2汁汗、MQ 如何保證消息冪等性問題?
1栗涂、業(yè)務(wù)場景知牌,先查詢 數(shù)據(jù)庫,如果已經(jīng)存在了斤程,就丟棄掉角寸。
2、記錄消費(fèi)日志忿墅,每成功一次扁藕,就把 messageKey 保存下來。
注意:
MQ 如果是 代碼錯誤 就不需要做重試了疚脐,
只有 鏈接超時 數(shù)據(jù)庫暫時鏈接不上才用重試機(jī)制
總結(jié): 基本上就這么幾個套路亿柑,真正應(yīng)用到實際中還是得看具體業(yè)務(wù)細(xì)節(jié)。
3棍弄、如何保證消息不丟失望薄?
就我們市面上常見的消息隊列而言,只要 配置得當(dāng)呼畸,我們的消息就不會丟痕支。
可以看出一共分為三個階段,分別是 生產(chǎn)消息蛮原、存儲消息和消費(fèi)消息卧须。我們從三個階段分別入手來看看如何確保消息不丟失。
生產(chǎn)消息方面:
生產(chǎn)者發(fā)送消息至Broker
儒陨,需要處理Broker
的響應(yīng)花嘶,不論是同步還是異步發(fā)送消息,同步和異步回調(diào)都需要做好try-catch
框全,妥善的處理響應(yīng)察绷,如果Broker
返回寫入失敗等錯誤消息,需要重試發(fā)送津辩。當(dāng)多次發(fā)送失敗需要作報警拆撼,日志記錄等容劳。
存儲消息方面:
存儲消息階段需要在消息刷盤之后再給生產(chǎn)者響應(yīng),假設(shè)消息寫入緩存中就返回響應(yīng)闸度,那么機(jī)器突然斷電這消息就沒了竭贩,而生產(chǎn)者以為已經(jīng)發(fā)送成功了。
如果Broker
是集群部署莺禁,有多副本機(jī)制留量,即消息不僅僅要寫入當(dāng)前Broker
,還需要寫入副本機(jī)中。那配置成至少寫入兩臺機(jī)子后再給生產(chǎn)者響應(yīng)哟冬。這樣基本上就能保證存儲的可靠了楼熄。
消費(fèi)消息方面:
消費(fèi)者應(yīng)該在 消費(fèi)者真正執(zhí)行完業(yè)務(wù)邏輯之后,再發(fā)送給Broker
消費(fèi)成功的確認(rèn)消息浩峡,這才是真正的消費(fèi)了可岂。
總結(jié)一下就是:
保證消息的可靠性需要三方配合。
生產(chǎn)者
需要處理好 Broker
的響應(yīng)翰灾,出錯情況下利用重試缕粹、報警等手段。
Broker
需要控制響應(yīng)的時機(jī)纸淮,單機(jī)情況下是消息刷盤后返回響應(yīng)平斩,集群多副本情況下,即發(fā)送至兩個副本及以上的情況下再返回響應(yīng)咽块。
消費(fèi)者
需要在執(zhí)行完真正的業(yè)務(wù)邏輯之后再返回響應(yīng)給Broker
绘面。
但是要注意消息可靠性增強(qiáng)了,性能就下降了糜芳,等待消息刷盤飒货、多副本同步后返回都會影響性能。因此還是看業(yè)務(wù)峭竣,例如日志的傳輸可能丟那么一兩條關(guān)系不大,因此沒必要等消息刷盤再響應(yīng)晃虫。
4皆撩、 MQ 如何保證消息的有序性。
有序性分為兩種:全局有序和部分有序哲银。
全局有序:
如果要保證消息的全局有序扛吞,首先只能由一個生產(chǎn)者往Topic
發(fā)送消息,并且一個Topic
內(nèi)部只能有一個隊列(分區(qū))荆责。消費(fèi)者也必須是單線程消費(fèi)這個隊列滥比。這樣的消息就是全局有序的!
部分有序:
因此絕大部分的有序需求是部分有序做院,部分有序我們就可以將Topic
內(nèi)部劃分成我們需要的隊列數(shù)盲泛,把消息通過特定的策略發(fā)往固定的隊列中濒持,然后每個隊列對應(yīng)一個單線程處理的消費(fèi)者。這樣即完成了部分有序的需求寺滚,又可以通過隊列數(shù)量的并發(fā)來提高消息處理效率柑营。
5、 如何處理消息的堆積村视?
消息的堆積往往是因為生產(chǎn)者的生產(chǎn)速度與消費(fèi)者的消費(fèi)速度不匹配官套。有可能是因為消息消費(fèi)失敗反復(fù)重試造成的,也有可能就是消費(fèi)者消費(fèi)能力弱蚁孔,漸漸地消息就積壓了奶赔。
因此我們需要先定位消費(fèi)慢的原因,如果是bug
則處理 bug
杠氢,如果是因為本身消費(fèi)能力較弱纺阔,我們可以優(yōu)化下消費(fèi)邏輯,比如之前是一條一條消息消費(fèi)處理的修然,這次我們批量處理膊升,比如數(shù)據(jù)庫的插入壤追,一條一條插和批量插效率是不一樣的。假如邏輯我們已經(jīng)都優(yōu)化了,但還是慢棒假,那就得考慮水平擴(kuò)容了,增加Topic
的隊列數(shù)和消費(fèi)者數(shù)量道宅,注意隊列數(shù)一定要增加萧豆,不然新增加的消費(fèi)者是沒東西消費(fèi)的。一個Topic中邻寿,一個隊列只會分配給一個消費(fèi)者蝎土。
今天就到這里啦,如果覺得好的話绣否,多多評論誊涯、點(diǎn)贊和關(guān)注呦~