nofile引數的學習與整理

济南小老虎發表於2024-06-11

nofile引數的學習與整理


背景

前段時間正好總結了檔案描述符洩露的問題. 
最近在客戶現場, 也遇到了一個問題. 
其實兩個問題都是因為nofile引數限制所引發.

所以總結一下:
nginx 的worker 的連線數是受到到 nofile的限制的. 
雖然那可以透過 修改配置檔案和 直接 ulimit -HSn進行修改.
但是真實情況下下 一個程序的限制是很難動態修改的. 
他一般是由啟動過程中的環境限制來決定. 
需要說明 -s reload 可能很難進行生效, 必須kill 再restart .  
不然不會生效. 

其實解決方案有多種. 
第一種是啟動指令碼之前 增加 ulimit -HSn 65536
第二種使用 systemd的服務進行管理 增加 
Restart=always
LimitNOFILE=64000
也可以避免這個問題. 
第三鍾就是常用的修改 /etc/security/limits.conf 進行持久化.
但是必須修改完,重新連線linux,再啟動,不然可能會無效. 

這裡面還一個問題是 ubuntu 不認 * 作為所有使用者的設定
這一點在不同作業系統時是不一樣的. 

最後還需要說明一定的是
要定期檢視 nginx 的errorlog 可以透過errorlog 快速定位問題

引數的理解

unix 的哲學是 anything is file 
每個程序能夠開啟的file數量就是收到 nofile的限制. 
核心裡面其實也有 fs.file-max  來決定整個系統最大的容量.
fs.file-nr  會表示整個系統的 開啟檔案數. 

linux 延續在 unix對file的描述. 
但是他的作用域是有一定的限制的.

引數作用域

fs.file-max 是整個系統的設定. 
ulimit -a 出來的 nofile 是單個程序的限制. 
/etc/security/limits.conf 裡面可以增加使用者對單獨的使用者進行限制. 
簡單期間可以使用如下的引數配置.
需要注意 * 代表所有使用者. 
注意, 這裡面有坑. * 在centos系可以這樣設定
但是ubuntu 是不認 * 的話.
soft 會告警.
hard 會直接阻斷不讓繼續建立檔案描述符. 

*   soft    memlock         unlimited
*   hard    memlock         unlimited
*   soft    nofile         unlimited
*   hard    nofile         unlimited
*   soft    nproc         unlimited
*   hard    nproc         unlimited

為了環境穩定和安全一般可以進行nginx開啟數量的限制
*   soft    memlock         204800
*   hard    memlock         204800
*   soft    nofile         204800
*   hard    nofile         204800
*   soft    nproc         204800
*   hard    nproc         204800

這裡面也需要說明. 理論上. java型別的應用. java開啟的執行緒
也會佔用檔案描述符的資源. 
開啟網路連線. 開啟前端檔案下載等都會佔用檔案描述符. 

一個出現問題的場景

/etc/security/limits.conf 內的設定會在下一次開啟bash 時生效. 
bash 啟動服務時 會根據自己的 限制作為母本來進行設定. 
透過nginx 進行驗證
第一種啟動方式:
ulimit -HSn 1025
./nginx 
然後: 執行命令
for i in `ps -ef |grep nginx |grep -v grep |awk '{print $2}'` ; do cat /proc/${i}/limits |grep files ; done

可以看到結果為:
Max open files            1025                 1025                 files
Max open files            1025                 1025                 files

然後修改一下 配置檔案, 但是不重新啟動 bash
vim /etc/security/limits.conf 增加配置為 204800 
再起重啟服務
Max open files            1025                 1025                 files
Max open files            1025                 1025                 files

透過 su 進行驗證
 killall nginx
 ./nginx  -c nginxtest.conf
 for i in `ps -ef |grep nginx |grep -v grep |awk '{print $2}'` ; do cat /proc/${i}/limits |grep files ; done
# 結果為: 
Max open files            1024                 1048576              files
Max open files            1024                 1048576              files
# 切換使用者
 su - root
 cd /data/nginx
 killall nginx
./nginx  -c nginxtest.conf
# 結果為:
for i in `ps -ef |grep nginx |grep -v grep |awk '{print $2}'` ; do cat /proc/${i}/limits |grep files ; done
Max open files            204800               204800               files
Max open files            204800               204800               files

新生成的bash 是有效果的. 

檢視nginx的檔案描述符開啟數量

for i in `ps -ef |grep nginx |grep -v grep |awk '{print $2}'` ; do ll /proc/${i}/fd |wc -l ; done
可以透過這個來簡單判斷 master 和 worker的開啟檔案數量資訊. 
如果超過限制可能會導致nginx出現大量的errorlog.

相關文章