解决 CentOS 7 下 Nginx 报 Too many open files

前几天在对开发环境中的服务进行压测时 Nginx 出现 Too many open files 的错误,这里记录下解决方法。

1.jpg

检查文件句柄

先来通过两个命令检查下 master 进程 和 worker 进程的文件句柄限制。

在 Nginx 运行时,检查当前 master 进程的限制:

1
2
3
cat /proc/$(cat /var/run/nginx.pid)/limits|grep open.files

Max open files 1024 4096 files

检查 worker 进程:

1
2
3
4
5
6
ps --ppid $(cat /var/run/nginx.pid) -o %p|sed '1d'|xargs -I{} cat /proc/{}/limits|grep open.files

Max open files 1024 4096 files
Max open files 1024 4096 files
Max open files 1024 4096 files
Max open files 1024 4096 files

上边返回结果的第二列和第三列分别为软限制(soft limit)和硬限制(hard limit),下边我们来对其进行调整。

调整限制

  1. /etc/sysctl.conf 中加上 fs.file-max = 70000
  2. /etc/security/limits.conf 中加上 nginx soft nofile 10000nginx hard nofile 30000
  3. 执行 sysctl -p 使配置生效
  4. /etc/nginx/nginx.conf 中加上 worker_rlimit_nofile 30000;

虽然 Nginx 可以通过 nginx -s reload 使配置生效,但这种方式并不会让全部进程都应用上新的配置,如果你在多核机器下,可以实验下:在执行这个操作后,通过检查 worker 进程句柄限制(方法见上文),还是有部分进程的句柄被限制为 S1024/H4096,即使试用 nginx -s quit 也不管用。解决方法是用 kill 命令杀掉 Nginx 后重新启动,这样所有的 Nginx 进程就都有了 S10000/H30000 的文件句柄限制。

1
2
pkill -9 nginx
systemctl start nginx

再次验证 worker 进程

1
2
3
4
5
6
ps --ppid $(cat /var/run/nginx.pid) -o %p|sed '1d'|xargs -I{} cat /proc/{}/limits|grep open.files

Max open files 30000 30000 files
Max open files 30000 30000 files
Max open files 30000 30000 files
Max open files 30000 30000 files

可以看到配置已在全部 worker 进程上生效。