1. 程式人生 > >一個定時任務導致的業務頻繁宕機事故

一個定時任務導致的業務頻繁宕機事故

現象和背景:

最近,一個客戶的mongodb經常發生記憶體不足的情況,由於對業務也未產生太大影響,也沒有太多關注。然而近期業務發生頻繁宕機,尤其近日,發生宕機的概率越來越大,一天宕機次數達7、8次之多,雖然每次僅有一分鐘故障時間,但整體影響還是不小。

歷史處理方式:

通過對java記憶體的監控,調整gc策略稍有所緩解,又對JVM整體記憶體進行調整,從原先的3G調整為7G,仍無法解決問題。後同事對該業務增加了定時監測應用介面的功能,如發現業務介面宕機,就自動重啟Java應用。常說“重啟是萬能的”,卻發現在這個業務場景下,重啟就顯得無能為力。

分析:

1、首先檢視主機監控(從記憶體、CPU、流量、IO、TCP等角度綜合分析),通過監控圖的檢視,我們發現異常時間時,Java應用主機的流量比較高。

2、流量高的幾個原因,一個是外部使用者訪問量(或攻擊類)的增加,從而導致應用主機流量增加,另一個是內部功能呼叫,應用主機與其他某些業務之間有關聯,從而導致流量增加。經過仔細分析後,我們排除了外部使用者量增加或者被攻擊的情況。然後我們篩選了所有伺服器的近3個小時的網路流量,發現mongodb和另一個業務的流量很高。伺服器內網流量監控
3、跟客戶溝通後,排出了另一個業務流量高導致當前應用主機異常的可能。然後著重JAVA應用主機和Mongodb伺服器的互動的排查。

4、既然是網路流量分析,就少不了ss工具,但通過ss的定時監控發現,應用主機和Mongodb資料庫的之間的連線數比較穩定,哪怕是在業務異常情況下,連線數也未有明顯變化。

5、開啟mongodb日誌,常規情況下我們開始了1s以上的慢查詢日誌,常規執行語句沒有開啟。

開啟命令:db.setProfilingLevel(2,0);具體見參考內容

6、開啟後,mongodb的日誌以每分鐘大概70M左右的速度在增長。10分鐘的日誌量差不多600M,語句執行量還是有點可觀的。

7、既然日誌出來,我們對日誌進行分析,mongodb比較好的日誌分析工具是mtools。安裝文件和使用說明見參考。然後是一堆的執行語句分析,從整理結果看,26-31分,這6分鐘的執行量都遠遠超出了正常值。mongodb執行語句統計
同樣也可以利用mtool工具去分析,命令:mloginfo mongod.log --queries

10分鐘的資料統計情況如下然後在這裡插入圖片描述
再根據的情況,將對應SQL語句發給客戶。

8、到這裡差不多可以了,研發童鞋可以通過大量的執行的SQL去找到大概是什麼業務在跑了。但在觀察業務流量監控圖形的時候,突然發現一個很規律的顯現,大概每30分鐘就有一次流量高峰,而每次流量高峰都將導致一次業務宕機。![規律性流量波動優化確認

於是將上述問題反饋給研發,經確認程式碼中的確存在這樣的定時任務,每次定時任務執行時間大概要10分鐘,而且是幾臺應用伺服器同事執行。建議研發童鞋將定時任務獨立出來用其中一臺伺服器單獨執行,但研發確認後,該定時任務是直接寫入各應用伺服器的記憶體的,沒有共享,快速恢復比較困難。且定時時間與應用啟動時間相關。

臨時解決方案:

與研發童鞋商議後將定時任務更改為24小時一執行,幾臺伺服器的啟動間隔分別延遲30分鐘後啟動,比如A伺服器啟動後,B伺服器上應用30分鐘後再重啟,避免定時任務同時執行時幾個應用都無響應,導致業務異常。

建議:

定時任務實現可配置化,任務獨立,不要與對外應用伺服器混在一起同時執行,在版本釋出時,指定其中一臺應用主機執行定時任務,同時關於定時結果的共享,可採用redis,mongodb進行處理。避免多個應用同時處理或者定時處理實效的情況。

參考:

Mtools命令使用:http://blog.csdn.net/xiewen99/article/details/52452328

設定mongodb日誌級別:http://blog.163.com/ji_1006/blog/static/1061234120134633710740/](https://img-blog.csdn.net/20181022145701330?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpcWl1bWFuMTgwNjg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)