消息隊列-如何解決消息隊列的延時以及過期失效問題?消息隊列滿了以後該怎麼處理?有幾百萬消息持續積壓幾小時,說說怎麼解決?

面試連環炮

面試題

如何解決消息隊列的延時以及過期失效問題?消息隊列滿了以後該怎麼處理?有百萬消息積壓接小時,說說解決思路?

剖析

MQ大幅度積壓這件事挺常見的,一般不出,出了的話就是大型生產事故,例如:消費端每次消費之後要寫MySQL,結果MySQL掛了,消費端就不動了,或者一直出錯,導致消息消費速度極其慢。

場景1:積壓大量消息

幾千萬的消息積壓在MQ中七八個小時,這也是一個真實遇到過的一個場景,確實是線上故障了,這個時候要不然就是修復consumer,讓他恢復消費速度,然後傻傻的等待幾個小時消費完畢,但是很顯然這是一種比較不機智的做法。

假設1個消費者1秒消費1000條,1秒3個消費者能消費3000條,一分鐘就是18萬條,1000萬條也需要花費1小時才能夠把消息處理掉,這個時候在設備允許的情況下,如何才能夠快速處理積壓的消息呢?

一般這個時候,只能夠做緊急的擴容操作了,具體操作步驟和思路如下所示:

  • 先修復consumer的問題,確保其恢復消費速度,然後將現有consumer都停止
  • 臨時建立好原先10倍或者20倍的queue數量
  • 然後寫一個臨時的分發數據的consumer程序,這個程序部署上去消費積壓的數據,消費之後不做耗時的處理,直接均勻輪詢寫入臨時建立好的10倍數量的queue
  • 接着臨時徵用10倍機器來部署consumer,每一批consumer消費一個臨時queue的數據
  • 這種做法相當於臨時將queue資源和consumer資源擴大了10倍,以正常的10倍速度

image-20200420160304030

也就是讓消費者把消息,重新寫入MQ中,然後在用 10倍的消費者來進行消費。

image-20200420160319662

場景2:大量消息積壓,並且設置了過期時間

假設你用的是RabbitMQ,RabbitMQ是可以設置過期時間的,就是TTL,如果消息在queue中積壓超過一定的時間,就會被RabbitMQ給清理掉,這個數據就沒了。這個時候就不是數據被大量積壓的問題,而是大量的數據被直接搞丟了。

這種情況下,就不是說要增加consumer消費積壓的消息,因爲實際上沒有啥積壓的,而是丟了大量的消息,我們可以採取的一個方案就是,批量重導,這個之前線上也有遇到類似的場景,就是大量的消息積壓的時候,然後就直接丟棄了數據,然後等高峯期過了之後,例如在晚上12點以後,就開始寫程序,將丟失的那批數據,寫個臨時程序,一點點查詢出來,然後重新 添加MQ裏面,把白天丟的數據,全部補回來。

假設1萬個訂單積壓在MQ裏面,沒有處理,其中1000個訂單都丟了,你只能手動寫程序把那1000個訂單查詢出來,然後手動發到MQ裏面去再補一次。

場景3:大量消息積壓,導致MQ磁盤滿了

如果走的方式是消息積壓在MQ裏,那麼如果你很長時間都沒有處理掉,此時導致MQ都快寫滿了,咋辦?

這個時候,也是因爲方案一執行的太慢了,只能寫一個臨時程序,接入數據來消費,然後消費一個丟棄一個,都不要了,快速消費掉所有的消息。然後走第二個方案,到凌晨的時候,在把消息填入MQ中進行消費。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章