1. 為什么產(chǎn)生消息堆積?
大多是因為 Consumer 出問題了荚虚,沒有及時發(fā)現(xiàn)薛夜,或者故障恢復(fù)需要較長的時間,導(dǎo)致大量消息積壓在 MQ 中版述。
2. 消息堆積會有什么后果呢梯澜?
2.1 消息被丟棄
例如 RabbitMQ 有一個消息過期時間 TTL,過期的消息會被扔掉渴析,這樣消息就徹底沒有了晚伙。
2.2 磁盤滿了
如果堆積量太大吮龄,可能導(dǎo)致磁盤空間不足,那么新消息就進不來了咆疗。
2.3 海量消息待處理
如果消息沒過期漓帚,并且磁盤空間也夠用,那么就是產(chǎn)生海量消息等待被消費午磁,Consumer 的噩夢尝抖。
3. 如何應(yīng)對呢?
3.1 消息被丟棄的情況
首先迅皇,要實現(xiàn)防止消息過期問題昧辽,不應(yīng)該設(shè)置過期時間。
如果就是設(shè)置了過期時間登颓,導(dǎo)致了消息丟失搅荞,怎么補救呢?
那就只能在夜深人靜挺据,趁著訪問量最低的時候取具,寫一個臨時程序來補消息了。
例如有訂單消息丟了扁耐,那就需要找出哪些訂單消息丟了暇检,然后重新發(fā)到隊列。
3.2 磁盤不足的情況
系統(tǒng)通常都是有監(jiān)控的婉称,達到空間閾值時就會發(fā)警報块仆,這時就要馬上處理了。
例如王暗,在其他機器上創(chuàng)建臨時的消息隊列悔据,再寫一個臨時的 Consumer,作為消息的中轉(zhuǎn)俗壹,把消息積壓隊列中的消息取出來科汗,放到臨時隊列里面去。
快速疏散積壓的消息绷雏,讓磁盤空間恢復(fù)正常水平头滔。
3.3 快速處理海量積壓消息
Consumer 恢復(fù)正常之后,面對堆積如山的消息涎显,怎么處理呢坤检?
如何按照之前正常情況處理的話,猴年馬月才能消費完期吓,此過程中還有新消息在不斷進來早歇。
例如,積壓了 100 萬條,有 3 個 Consumer箭跳,每一個每秒能處理 200 條晨另,3 個 Consumer 每秒一共能處理 600 條。
大概需要一個多小時才能處理完谱姓。
這一個多小時又會積壓多少新的消息呢拯刁?
所以正常處理肯定不行,需要提速逝段。
例如 Kafka,這個消息積壓的 Topic 有 3 個 Partition割捅,那最多就能用 3 個 Consumer奶躯,所以增加 Consumer 沒有用。
還是可以使用臨時隊列的方式亿驾。
新建一個 Topic嘹黔,設(shè)置為 20 個 Partition
Consumer 不再處理業(yè)務(wù)邏輯了,只負責(zé)搬運莫瞬,把消息放到臨時 Topic 中
這 20 個 Partition 可以有 20個 Consumer 了儡蔓,它們來處理原來的業(yè)務(wù)邏輯。
這 20 個 Consumer 每秒一共能處理 4000 條了疼邀,這樣幾分鐘就可以處理完積壓的 100 萬條喂江。
這幾分鐘新來的消息也不會太多,所以很快就可以恢復(fù)正常水平旁振,之后获询,再把整體結(jié)構(gòu)恢復(fù)為原來的形式。
小結(jié)一下拐袜,消息積壓還是比較麻煩的吉嚣,最好是提前防范,做好硬件和消息系統(tǒng)的健康監(jiān)控蹬铺。如果出現(xiàn)消息丟失尝哆,就要人工查找丟失的消息,然后補上甜攀。在消費不過來的時候秋泄,可以考慮使用臨時隊列作為中轉(zhuǎn),提升處理能力赴邻。
推薦閱讀