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