線上百萬 MQ 消息積壓的快速處理方案
在我們日常的生產環境上,由於某些原因(如消費者代碼中 bug、消費者端使用的中間件存在性能問題)導致消費者不能處理消息或者消費者處理速度極慢進而導致了線上出現百萬的消息積壓。
假設現在存在百萬消息在消息隊列中堆積,我們如何快速的消費完這些消息呢?
1、優化消費者的代碼
由於消費者現在是消費速度不夠導致了 MQ 消息的積壓,所以我們可以將消費的代碼做優化(如減少業務中不必要的計算,採用多線程的方式消費等等)來提高消費者的速度。
假設消費者機器有兩臺,代碼優化前是 200 條 / 秒的消費速度,代碼優化後消費者的消費速度提到了 400 條 / 秒;這樣的兩臺機器 1 小時可以消費消息條數是:4006060*2=2880000 條 / 小時,所以百萬消息的積壓預估是需要 1 小時纔可以完成消費完成。線上一些特殊的業務是不允許這樣的時間延遲。
2、新建臨時 topic
假設原先 topic 是兩個分區,消費者消費消息的業務邏輯中有數據持久化等相對耗時的操作。
由於 MQ 中有大量的消息積壓,爲此我們將消費者的代碼做一些調整,即就是消費者不做實際的業務處理,而是將消息轉發到臨時的 topic 中(temp_topic),並且在臨時的 topic 中增加是原來若干倍(如設置成原來的 10 倍)的分區
然後增加臨時的機器來消費臨時 topic 上的消息,將原先的業務邏輯放在臨時的消息中完成。
等 MQ(topic1)中的消息被快速消費完之後將不在向臨時的 topic 中轉發消息並且臨時的消費者機器下掉,繼續執行原下的邏輯。
本方案要注意如下幾點:
(1)增了臨時 topic 分區和臨時消費者機器,數據庫可能會承受不了壓力而導致崩潰,所以最好要做一些數據庫保護措施。
(2)針對一些設置了失效時間的 MQ 消息,由於積壓在 MQ 隊列中時間過長導致消息失效了。爲了保證數據不丟失,我們需要手動處理業務數據(如通過定時任務的方式將數據失效的 MQ 消息再重新發送一次)。
(3)消息積壓也可能會導致某些分區無法再存儲新生產的消息,導致消息丟失。針對這樣的業務我們也需要手動地處理業務。
是否只增加消費者機器而不做分區的擴容呢?
現在由於性能的瓶頸在 MQ 的分區上,即使增加了消費者機器消費的速度還是很慢的。
總結:
針對線上 MQ 消息大量積壓的問題,我們首先要做好消息積壓到一定量之後做告警措施(如發短信或者郵件通知給負責人),然後排查和解決消費者問題(如修復消費者的 bug 或者消費者端消費的性能瓶頸問題),如果還存在大量的消息積壓的問題,最後再採用新建臨時 topic 的方式去快速消費積壓的消息。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/UpWrM2iyM5KAZxufPuUETA