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.