一、mq消息積壓中,mq掛了的處理方法
如果MQ掛掉,勢必會影響發(fā)消息的邏輯,MQ不像數(shù)據(jù)庫,掛了就沒辦法進(jìn)行任何操作了。MQ本身就是用于多系統(tǒng)解耦,異步處理等場景的,就算MQ掛了,也不會影響到主流程,所以這其實就相當(dāng)于是一個降級的處理。
1、降級處理,數(shù)據(jù)存儲
降級可以有兩種方式,一種是將要發(fā)送的消息存儲到數(shù)據(jù)庫中,另一種就是直接寫本地磁盤。
寫數(shù)據(jù)庫:寫數(shù)據(jù)庫相對來說比較簡單,本身程序中都會用到數(shù)據(jù)庫,這個時候只需要單獨加一張表即可。當(dāng)消息發(fā)送異常的時候,將消息進(jìn)行存儲。寫磁盤:寫磁盤跟數(shù)據(jù)庫的作用是一樣,寫磁盤相對來說更加獨立,不依賴數(shù)據(jù)庫。不好的點在于寫磁盤還得考慮寫入的格式,比如消息量大要不要分多個文件寫入之類的問題,整體需要考慮的點比數(shù)據(jù)庫要多。寫日志:寫日志可能是最簡單的方式了,但是在后期消息補(bǔ)發(fā)的時候就需要人工介入,將失敗的消息撈出來然后重新發(fā)送。2、重發(fā)消息
可以單獨起一個定時任務(wù),周期性的去將這些失敗存儲的消息進(jìn)行重發(fā),如果你的MQ服務(wù)故障后幾分鐘就恢復(fù)了,那么重試的時候消息就能夠成功發(fā)出去了。也可以人工處理,最重要的是當(dāng)MQ故障的時候,消息發(fā)送不出去,這些消息要存儲起來,不能丟失,這才是重點。
完整流程如下:
集群環(huán)境下,MQ全部掛掉的概率非常低,某個掛掉的話,大部分成熟框架都有相應(yīng)的處理策略。
二、mq消息積壓中,mysql掛了的處理方法
當(dāng) MySQL 掛掉時,消息隊列(MQ)還在運行,如果這時 MQ 中的消息積壓嚴(yán)重,可能會出現(xiàn)因為 MQ 發(fā)送消息導(dǎo)致 MySQL 崩潰的情況。這時候需要采用以下方法來處理:
1、停止 MQ 的消息發(fā)送服務(wù)
停止 MQ 的消息發(fā)送服務(wù),避免繼續(xù)向 MySQL 中寫入數(shù)據(jù),直到 MySQL 恢復(fù)運行。
2、處理消息
對于已經(jīng)發(fā)送成功但尚未被消費的消息,可以考慮將其存儲到本地文件或 Redis 等緩存中,等待 MySQL 恢復(fù)后再進(jìn)行數(shù)據(jù)同步操作。對于正在發(fā)送的消息,可以將其暫時存儲到臨時隊列(如 RabbitMQ 的 Dead Letter Exchange),等待 MySQL 恢復(fù)后再重新發(fā)送到正式隊列。3、檢查數(shù)據(jù)庫表的狀態(tài)
在 MQ 重新啟動之前,需要檢查數(shù)據(jù)庫表的狀態(tài),并對一些不一致的數(shù)據(jù)進(jìn)行修復(fù)。例如,可以從本地文件或者 Redis 緩存中讀取數(shù)據(jù)并同步到 MySQL 數(shù)據(jù)庫中。
三、mq消息積壓中,mq和mysql都掛了的處理方法
當(dāng)消息隊列(MQ)和 MySQL 都出現(xiàn)故障時,可能會導(dǎo)致業(yè)務(wù)系統(tǒng)不能正常運行、數(shù)據(jù)丟失甚至損壞,這時候需要采用一些應(yīng)急措施來處理:
1、啟動備份 MQ 和 MySQL
在系統(tǒng)正式運行之前,需要配置好備份 MQ 和 MySQL,當(dāng)發(fā)生故障時,可以快速切換到備份服務(wù)器上,保證業(yè)務(wù)的連續(xù)性。
2、使用分布式事務(wù)機(jī)制
在應(yīng)用程序中引入分布式事務(wù)機(jī)制,對應(yīng)用程序的操作進(jìn)行封裝,保證 MQ 和 MySQL 數(shù)據(jù)庫事務(wù)的一致性,防止數(shù)據(jù)的丟失或損壞。
3、采取數(shù)據(jù)恢復(fù)措施
如果 MQ 和 MySQL 同時出現(xiàn)故障,需要優(yōu)先恢復(fù) MySQL 數(shù)據(jù)庫。可以使用數(shù)據(jù)庫備份和恢復(fù)工具來恢復(fù)數(shù)據(jù),最大程度上避免數(shù)據(jù)的丟失和損壞。
4、進(jìn)行容災(zāi)演練
定期進(jìn)行容災(zāi)演練,驗證備份 MQ 和 MySQL 的可用性、數(shù)據(jù)的一致性以及故障恢復(fù)的時間,優(yōu)化容災(zāi)方案,提高系統(tǒng)的容錯能力和可靠性。
四、MQ 消息積壓處理
消費端出了問題,導(dǎo)致消息隊列消息積壓了很多或者集群的磁盤都快寫滿了。
解決思路有兩個:
MQ動態(tài)擴(kuò)容,將MQ容量增大,讓其能容納更多的消息消費端加大消費能力,迅速處理掉積壓。1、名列前茅個例子
如果你積壓了幾百萬到上千萬的數(shù)據(jù),即使消費者恢復(fù)了,也需要大概1小時的時間才能恢復(fù)過來。一般這個時候,只能操作臨時緊急擴(kuò)容了,具體操作步驟和思路如下:
先修復(fù)consumer的問題,確保其恢復(fù)消費速度,然后將現(xiàn)有cnosumer都停掉新建一個較好ic,partition是原來的10倍,臨時建立好原先10倍或者20倍的queue數(shù)量然后寫一個臨時的分發(fā)數(shù)據(jù)的consumer程序,這個程序部署上去消費積壓的數(shù)據(jù),消費之后不做耗時的處理,直接均勻輪詢寫入臨時建立好的10倍數(shù)量的queue接著臨時征用10倍的機(jī)器來部署consumer,每一批consumer消費一個臨時queue的數(shù)據(jù)這種做法相當(dāng)于是臨時將queue資源和consumer資源擴(kuò)大10倍,以正常的10倍速度來消費數(shù)據(jù)等快速消費完積壓數(shù)據(jù)之后,得恢復(fù)原先部署架構(gòu),重新用原先的consumer機(jī)器來消費消息2、第二個例子
由于長期積壓,導(dǎo)致消息的過期時間快到了。不過生產(chǎn)環(huán)境一般很少會設(shè)置消息過期。rabbitmq是可以設(shè)置過期時間的,就是TTL,如果消息在queue中積壓超過一定的時間就會被rabbitmq給清理掉,這個數(shù)據(jù)就沒了。這時可以讓這批數(shù)據(jù)先過期,后面再去補(bǔ)。等過了高峰期以后,將丟失的那批數(shù)據(jù),寫個臨時程序,一點一點的查出來,然后重新灌入mq里面去,把白天丟的數(shù)據(jù)補(bǔ)回來。
延伸閱讀1:什么是消息隊列
消息隊列是一種先進(jìn)先出的隊列型數(shù)據(jù)結(jié)構(gòu),實際上是系統(tǒng)內(nèi)核中的一個內(nèi)部鏈表。消息被順序插入隊列中,其中發(fā)送進(jìn)程將消息添加到隊列末尾,接受進(jìn)程從隊列頭讀取消息。多個進(jìn)程可同時向一個消息隊列發(fā)送消息,也可以同時從一個消息隊列中接收消息。發(fā)送進(jìn)程把消息發(fā)送到隊列尾部,接受進(jìn)程從消息隊列頭部讀取消息,消息一旦被讀出就從隊列中刪除。