記一次奇怪的檔案控制程式碼洩露問題

2023-12-03 21:00:37

記錄並分享一下最近工作中遇到的 Too many open files 異常的解決過程。

問題背景

產品有個上傳壓縮包並匯入設定資訊到資料庫中的功能,主要流程如下:

  1. 使用者上傳壓縮包;
  2. 後端解壓存放在臨時目錄,並返回列表給使用者;
  3. 使用者選擇需要匯入哪些資訊;
  4. 後端按需插入資料庫中,完成後刪除臨時目錄。

這個功能上線兩三年了,一直沒出現問題,最近測試在功能迴歸時,匯入的時候出現Too many open files異常。

但是通過lsof -p pid | wc -l檢視當前程序開啟的控制程式碼數時,又是正常的。

Too many open files是Linux系統中常見的錯誤,字面意思就是說開啟了太多的檔案,超過了系統的限制。

這裡的檔案(file)更準確的意思是檔案控制程式碼,或者是檔案描述符。可以說,Linux系統裡的一切都是檔案,包括網路連線、埠等等。

lsof -p pid命令可以檢視指定程序當前開啟的檔案資訊。wc -l命令指按行統計。

問題分析

當時的第一反應是該系統的檔案控制程式碼數設定的太低了,因為在其他環境都是正常的。

通過ulimit -a命令,可以檢視當前系統對各種資源的限制。

[uyong@linuxtest ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31767
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 4096
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 31767
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

open files 那行就是表示開啟的檔案數限制,即一個程序最多可以同時開啟的檔案數。

也可以通過ulimit -n直接檢視最大開啟檔案數量。

當時查出來的設定是4096,檢視其他沒問題的環境上的設定,數量都是遠遠大於這個數。而且系統重新啟動後,沒做任何操作時,通過lsof -p pid | wc -l檢視檔案佔用,只有100多個。在好的環境上執行匯入成功後,再次檢視,檔案佔用數不變。在有問題的環境上匯入失敗後,檢視檔案佔用數也是不變。

雖然當時的壓縮包檔案很大,但4096按說也夠的。有點奇怪,為了不影響測試進度,只能先臨時修改系統設定,增大檔案數限制,ulimit -n 65535命令執行後,再次匯入沒問題了。

命令ulimit -n 65536只能臨時臨時調整檔案數量,系統重啟後設定就會失效。

如果要永久生效,需要在組態檔/etc/security/limits.conf裡增加如下兩行:

* soft nofile 65536
* hard nofile 65535

問題到此就結束了嗎,NO