mq使用不當,造成生產線上環境的服務奔潰問題記錄

2021-10-07 19:17:17 字數 1148 閱讀 7867

線上採用canel監聽a表的status狀態變化,只要有變化就通過mq傳送訊息到對應的消費者端處理。

消費者端的程式**這樣子寫(因涉及公司業務,這裡只是舉個大致的**示例)

**大致的思路就是,監聽佇列queue_b,然後消費傳送到queue_b的訊息,如果消費過程中發生異常,就將訊息重新發回佇列中去。

一開始上線這個功能是正常的,因為dosomething業務裡面沒有任何異常,訊息能夠被正常消費。

後來某個版本上線後,突然有一天晚上,發現線上的服務,大部分宕機,監控簡訊響個不停。

經核實,就是因為dosomething裡面的**異常了,導致mq消費失敗,然後**裡又將訊息重新推回佇列中。這樣子問題就來。

程式本身有問題,mq消費訊息永遠是失敗的,然後又剛好設定重新歸隊,導致一直在刷mq消費失敗的日誌,結果80g的磁碟沒多久就撐爆了,導致同伺服器的其他服務因為磁碟寫入日誌的問題,全線奔潰。。。代價有點慘重。

@component

@slf4j

public class msgreceiverb catch (exception e) ",e.getmessage());

channel.basicreject(message.getmessageproperties().getdeliverytag(),true);}}

private void dosomething()

}

出現這種問題的原因:開發對應業務的同事對mq的特性不是很熟悉。雖然一開始沒有問題,但是埋下了隱患。後來某同事

因需求變動,導致dosomething()**拋錯就成了引爆這個導火線的人,直接導致了這次線上事故的發生。

筆者認為合理的處理方式有以下幾種

第一種:訊息消費失敗後,不要設定重新歸隊,因為**沒有執行手工確認這個動作,訊息是不會從mq中移出的,也就是訊息

不會丟失,等消費者下次再啟動的時候,就會重新消費。

第二種:訊息消費失敗後,直接讓訊息進入死信佇列,在死信佇列裡,再起消費端重新消費,如果消費幾次還是失敗的話,

發訊息通知人工處理。(根據訊息的重要性判斷是否需要人工處理,還是直接丟棄)

第三種:訊息消費失敗,直接持久化到資料庫,nosql資料庫或者sql資料庫都可以,然後再發訊息人工介入處理。(根據訊息的重要性判斷是否需要人工處理,還是直接丟棄)

快取如果使用不當會造成什麼後果?

了解什麼是 redis 的雪崩和穿透?redis 崩潰之後會怎麼樣?系統該如何應對這種情況?如何處理 redis 的穿透?對於系統 a,假設每天高峰期每秒 5000 個請求,本來快取在高峰期可以扛住每秒 4000 個請求,但是快取機器意外發生了全盤宕機。快取掛了,此時 1 秒 5000 個請求全部落...

ThinkPHP使用不當可能造成敏感資訊洩露

thinkphp在開啟debug的情況下會在runtime目錄下生成日誌,而且debug很多站都沒關的,所以影響應該很大吧 我們來看一下thinkphp3.2版本生成日誌結構 thinkphp3.1結構 runtime logs home 16 09 09.log 可以看到是 專案名 runtime...

c thread 使用不當導致的崩潰問題

看個例子 1 class ctimer7 開始8void start 914 15void run 1622 23 結束24 void stop 2532 33 private 34 std thread t 35 std thread t1 36int i 37 bool b exit 38 39...