生产 Nginx 转发服务器,抛出大量 (24: Too many open files) while connecting to upstream :
1 原因分析
Linux 中所有的资源都是以文件的形式存在,句柄可以理解为指向这些文件的指针。对于这些句柄, Linux 是有数量限制的,单个进程默认可以打开的句柄数上限,可以用以下命令来查看:
ulimit -a
使用以下命令就可以查询到当前系统的连接状态:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
状态 | 说明 |
---|---|
TIME_WAIT | 表示收到了对方的 FIN 报文,并发送出了 ACK 报文。 |
FIN_WAIT_1 | 当 SOCKET 在 ESTABLISHED 状态时,它想主动关闭连接,向对方发送了 FIN 报文,此时该 SOCKET 进入到 FIN _WAIT_1状态。而当对方回应 ACK 报文后,则进入到 FIN _WAIT_2状态。 |
ESTABLISHED | 表示 TCP 连接已经成功建立。 |
LAST_ACK | 当被动关闭的一方在发送 FIN 报文后,等待对方的 ACK 报文的时候,就处于 LAST_ ACK 状态。 |
可以发现总数已经超过最大的限制了。
使用该命令也可以:
lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more
lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。
第一列是打开的句柄数;第二列是 PID。
通过以下命令进入 PID,查询到所对应的进程:
cd /proc/[pid]
ll
2 解决
使用 ulimit 命令,扩大其进程所能打开的句柄数量:
ulimit -n 2048
修改后: