起因及癥狀
最近,我們的一臺服務器隨著運行時間的增加,逐漸出現了壓力過大的問題。具體表現為數據庫連接數飆升至 4000+,Redis 頻繁超時,系統報錯文件打開數過多等。針對這些問題,我們逐一檢查了數據庫連接池、Redis 連接池以及系統的 ulimit 配置,但都未能找到問題的根源。
一次意外的服務器死機重啟后,系統性能短暫恢復正常,但隨著時間的推移,問題又再次出現。通過 ps 命令查看進程狀態,發現一個 crontab 任務的進程堆積如山。這個任務的執行間隔是 1 分鐘,正常情況下是可以在 1 分鐘內執行完畢的。然而,隨著業務的快速擴展,該任務的執行時間逐漸延長,導致原本的防止堆積措施失效。
問題分析
crontab 是一種簡單且有效的任務調度工具,但如果使用不當,尤其是對執行時間較長的任務,可能會導致嚴重的系統性能問題。此次事件的根本原因在于任務的執行時間超過了預設的間隔時間,導致新任務不斷啟動,而舊任務還未完成,進而造成進程堆積,系統資源耗盡。
解決方案
針對這個問題,我們提出了以下兩種解決方案:
方案 1:任務執行時設置 PID 標志,避免重復啟動
通過在任務開始執行時創建一個 PID 文件,記錄當前任務的進程 ID。下一次任務啟動時,先檢查該 PID 文件是否存