線上採用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...