Nginx reload重新加载配置文件的异常情况

发布时间 2023-12-29 12:10:05作者: 济南小老虎

Nginx reload重新加载配置文件的异常情况


背景

临近年底, 很多业务工作量都上来了. 
今天同事告知, nginx的log 里面出现了大量的 too many openfiles 的提示信息.
并且同事明确说明, 已经修改了/etc/secuirty/limits.conf 以及 worker_connections 这两个参数. 
并且已经第一时间执行了reload 的操作. 
理论上不应该再出现这个提示了才对. 
基于这个问题场景, 简单总结一下这次的问题以及简单应对.

结论

nginx -s reload 
其实是一个 soft 的过程. 
他需要等待 nginx 的worker 处理完手工的工作再重新拉起来一个进程进行工作. 
所以有一定的概率会出现 有的worker 一直繁忙, 无法清理已有的链接, 导致一直无法重新加载配置文件.

这里就有两个问题. 加载配置文件 会使用用户的 security的配置进行生效. 
并且使用nginx.conf 里面的新内容
如果一直无法重启进程, 那么大的最大文件打开数是不会发生变化的. 

优雅都是有成本的, 不仅仅是生活, 程序也是如此. 

论据

在 anything is file 的linux 系统中. 
会通过文件的方式记录 运行程序的全部内容. 
/proc/$pid 里面
其中 fd 应该是打开的文件句柄信息
limits 应该是配置限制信息: 
可以通过如下命令进行确认: 
ps -eo lstart,etime,time,cmd |grep nginx
# 查看每个nginx进程的启动时间等信息. 
# 如果看到 worker进程不一致的时间, 可能就是存在一定的问题. 
for i in `ps -ef |grep nginx |grep -v grep |awk '{print $2}'`; do echo $i ; cat /proc/$i/limits |grep "open files"; done
# 查看每个nginx进程的限制信息.  
# 可以看到他的配置情况

如果有几个 worker 进程还处于 reload 之前的时间点启动的
那么很有可能 修改的配置还未生效.  所以建议稳妥起见在非工作时间 还行一下 restart 最好不过. 

关于两个参数-worker_rlimit_nofile

worker_rlimit_nofile
worker_connections

这两个参数是不一样的维度. 
第一个: worker_rlimit_nofile
worker_rlimit_nofile  如果这个参数没有设置
那么默认就去用户的limit限制信息. 

如果这个参数设置了就会覆盖 用户的limit限制, 并且可以可以低 
并且是针对一个worker进程来的. 

可以根据下面的设置明显的看出来
这个只是影响worker的线程信息, 不影响 master的
并且可以脱离nofile系统设置

所以如果没有系统管理员权限的话, 可以作为一个使用点进行优化. 

[root@auto109 fd]# ulimit -n
66666

# 不加参数
[root@auto109 fd]# for i in `ps -ef |grep nginx |grep -v grep |awk '{print $2}'`; do echo $i ; cat /proc/$i/limits |grep "open files"; done
9529
Max open files            66666                66666                files
9530
Max open files            66666                66666                files
[root@auto109 fd]# vim /usr/local/nginx/nginx.conf
[root@auto109 fd]# systemctl restart nginx

# 参数为 102400 
[root@auto109 fd]# for i in `ps -ef |grep nginx |grep -v grep |awk '{print $2}'`; do echo $i ; cat /proc/$i/limits |grep "open files"; done
16515
Max open files            66666                66666                files
16516
Max open files            102400               102400               files

# 修改参数为 1024 
[root@auto109 fd]# vim /usr/local/nginx/nginx.conf
[root@auto109 fd]# systemctl restart nginx
[root@auto109 fd]# for i in `ps -ef |grep nginx |grep -v grep |awk '{print $2}'`; do echo $i ; cat /proc/$i/limits |grep "open files"; done
17209
Max open files            66666                66666                files
17210
Max open files            1024                 1024                 files
[root@auto109 fd]#

关于参数-worker_connections

需要注意 要区分 nginx是作为应用服务器还是作为反向代理服务器. 
http1.1 一个chrome浏览器可以打开 六个tcp链接. 理论上就需要nginx 开启至少6个文件openfile

如果是反向代理可能要乘以 2 

所以应用服务器能够支撑的 在线用户信息可能为:

worker的数量 * min[worker_connections , worker_rlimit_nofile}/12

所以还是需要关注这个参数的.