/proc/pid/fd 中打开的套接字数量与 netstat 不一致

/proc/pid/fd 中打开的套接字数量与 netstat 不一致

我在运行自己的爬网程序时遇到了一个奇怪的套接字问题。由于协议设计,它可以快速打开和关闭大量 TCP 套接字。这是我必须忍受的事情。我非常确定在代码中我已经正确关闭了套接字(通过strace和调试打印进行验证)。但不知何故,我仍然达到了系统的开放套接字限制。 Netdat 等工具也显示打开套接字的数量有所增加。经进一步检查。我发现里面有大量的套接字文件描述符/proc/<pid>/fd/。这是我运行的示例结果

所有命令都执行为root

# ls /proc/248298/fd/ -l | grep socket | wc -l
522

但是,当我运行netstat以找出套接字连接到哪个远程时,同时考虑系统范围的 TIME_WAIT 和 CLOSE_WAIT 套接字(因为 netstat 不再将它们与我的进程关联)。这个数字要低得多。

# netstat -tulnap | egrep '(TIME_WAIT|CLOSE_WAIT|248298)' | wc -l
109

我尝试将其设置net.ipv4.tcp_tw_reuse1缓解措施,但没有成功。

这是什么原因呢?更进一步,为什么我关闭的套接字仍然被认为是活动的?或者有办法解决这个问题吗?

操作系统:Linux
发行版:Ubuntu 22.04
内核:5.15
CPU:x64

答案1

这称为短暂端口压力,可能会影响高流量系统,这些系统会与各种其他服务建立大量连接,其中包括不太合法的网络流量。操作系统为此保留的端口各不相同,RFC 关于端口范围的建议也各不相同(比较 RFC 6056、RFC 6335)。

在 Linux 上最简单的旋钮是net.ipv4.ip_local_port_range ,对于进行大量连接的系统,可能应该将其设置得尽可能大:

sysctl -w net.ipv4.ip_local_port_range=1024\ 65535

这可能会导致使用 1024 到 65535 范围内的端口的其他网络服务出现问题(可能是 NFS 的 RPC?)。或者,为了测试其他方法的有效性,可以故意将该值设置得较小,以使有问题的状态更容易重现:

sysctl -w net.ipv4.ip_local_port_range=30000\ 30100

这么低的范围当然可能会破坏随机服务。建议使用测试虚拟机或提供对测试系统的控制台访问。

否则,有各种旋钮可以减少连接在各种状态下花费的时间长度(您没有 FIN_WAIT*在问题中列出任何可能导致计数关闭的状态),但如果设置得太低,这些可能会增加风险各种问题,例如出现延迟或重复的数据包时。如果远程系统由于速率限制而丢弃数据包,则这种情况不太可能发生。

相关内容