如何检查nginx打开socket数量

nginx在大并发的场景下,会出现CPU占用过高,请求响应慢的问题,在错误日志中通常表现为Too many open files,即它进入了超出系统允许的打开文件数量并开始拒绝请求的状态。在这种情况下可以检查nginx打开的socket数量,优化nginx配置。

我们可以使用以下命令找出系统上允许打开的文件的最大数量:

$ ulimit -n
1024

我们的假设是某些套接字连接从未关闭,因此打开的文件数一直在缓慢上升,直到超过限制。

我们想检查nginx打开了多少个套接字,因此首先我们需要知道它在下面运行的进程ID:

$ ps aux | grep nginx | grep -v grep
root      1089  0.0  0.7 105152  2736 ?        Ss   17:34   0:00 nginx: master process /usr/sbin/nginx
www-data 17474  0.0  0.6 105300  2296 ?        S    21:49   0:04 nginx: worker process
www-data 17475  0.0  0.7 105300  2856 ?        S    21:49   0:04 nginx: worker process
www-data 17476  0.0  0.7 105300  2792 ?        S    21:49   0:03 nginx: worker process
www-data 17477  0.0  0.7 105300  2668 ?        S    21:49   0:04 nginx: worker process

因此,nginx的进程进程ID是1089、17474、17475、17476和17477。

我们可以使用以下命令检查打开了哪些文件描述符:

$ sudo ls -alh /proc/{1089,17{474,475,476,477}}/fd
/proc/17476/fd:
total 0
dr-x------ 2 www-data www-data  0 Apr 23 23:40 .
...
l-wx------ 1 www-data www-data 64 Apr 23 23:40 6 -> /var/log/nginx/error.log
l-wx------ 1 www-data www-data 64 Apr 23 23:40 7 -> /var/www/thinkingingraphs/shared/log/nginx_access.log
l-wx------ 1 www-data www-data 64 Apr 23 23:40 8 -> /var/www/thinkingingraphs/shared/log/nginx_error.log
lrwx------ 1 www-data www-data 64 Apr 23 23:40 9 -> socket:[8910]

/proc/17477/fd:
total 0
...
lrwx------ 1 www-data www-data 64 Apr 23 23:40 56 -> socket:[52213]
lrwx------ 1 www-data www-data 64 Apr 23 23:40 57 -> anon_inode:[eventpoll]
l-wx------ 1 www-data www-data 64 Apr 23 23:40 6 -> /var/log/nginx/error.log
l-wx------ 1 www-data www-data 64 Apr 23 23:40 7 -> /var/www/thinkingingraphs/shared/log/nginx_access.log
l-wx------ 1 www-data www-data 64 Apr 23 23:40 8 -> /var/www/thinkingingraphs/shared/log/nginx_error.log
lrwx------ 1 www-data www-data 64 Apr 23 23:40 9 -> socket:[8910]

我们可以缩小范围以仅显示打开了多少个套接字:

$ sudo ls -alh /proc/{1089,17{474,475,476,477}}/fd | grep socket  | wc -l
189

我们也可以使用lsof,尽管由于某些原因返回的数字略有不同:

$ sudo lsof -p 1089,17474,17475,17476,17477 | grep socket | wc -l
184

使用括号扩展来做到这一点

$ sudo lsof -p `echo {1089,174{74,75,76,77}} | sed 's/ /,/g'` | grep socket | wc -l
184
Elasticsearch集群脑裂问题详解
多租户架构
Tags: