暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

nofile参数的学习与整理

济南小老虎 2024-06-11
165

背景

前段时间正好总结了文件描述符泄露的问题. 
最近在客户现场, 也遇到了一个问题.
其实两个问题都是因为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.


文章转载自济南小老虎,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论