我已经做了尽可能多的研究,而不用在内核源代码中进行挖掘。 关于这个问题似乎有大量的虚假信息/不正确的信息,所以我希望这个答案为我和其他人一劳永逸。
严格的讲IPv4,实际上是端口耗尽的可能吗? 让我解释:
这就是问题:这是如何工作的?
最后,我对输出的临时端口和正在监听的input端口有些困惑。 我意识到一旦build立连接,连接的每一边都是对等的,但在此之前:
例如,如果确实(srcip,srcport,dstip,dstport)元组必须是唯一的,为什么如果我启用,例如
net.ipv4.ip_local_port_range = 1024 65535
它允许使用从1024-65535的短暂端口,如果我的服务绑定在端口3306上(例如mySQL),它们有时会因端口正在使用而无法启动。
这与这个事实有关:(这是我要求validation的一个陈述):
我可以validation上述行为,即我使用上面的确切的sysctl行,因为它我把mySQL移动到一个低于1024的端口,因为它会偶尔和非常随机地重新启动,因为假设操作系统使用该端口(3306)为一个短暂的港口。
这里有两个主要的问题:
严格的讲IPv4,实际上是端口耗尽的可能吗?
是。 以负载平衡路由器为例,将所有连接发送到NAT IP地址。 当您有许多SRC IP
连接到单个DST IP
的瓶颈时,可能会发生这种情况。
这意味着您的networking服务器可能有一堆连接,如:
root@buglab:~# netstat -pnt Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 173.200.1.18:80 10.100.1.100:49923 ESTABLISHED 13939/nginx: worker tcp 0 0 173.200.1.18:80 10.200.1.200:10155 ESTABLISHED 13939/nginx: worker tcp 0 0 173.200.1.18:80 10.10.1.10:14400 ESTABLISHED 13939/nginx: worker tcp 0 0 173.200.1.18:80 10.10.1.10:50652 ESTABLISHED 13939/nginx: worker tcp 0 0 173.200.1.18:80 10.20.1.20:57554 ESTABLISHED 13939/nginx: worker
这很好。 但是,如果所有的“外部地址”都是相同的,这可能会导致一个问题(例如,“一个IP地址执行NAT的大型路由器”)。
如果我不得不假设为什么短暂的端口耗尽不是一个普遍的问题,我build议这是因为每个端口都需要一个监听服务和足够的资源来响应 – 另一个资源(内存,CPU)通常是第一个瓶颈。
但是,在负载均衡公司工作时,我亲自遇到了一些端口耗尽问题。
“这允许使用从1024-65535的短暂端口,如果我的服务绑定在端口3306上(例如mySQL),它们有时会因为端口正在使用而无法启动。
如果mySQL服务器正在使用,则不能绑定到该端口 – 比如localhost:3306或所有接口。 例如,请参阅以下netstat
输出中的0.0.0.0:80行?
root@buglab:~# netstat -lnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 964/php-fpm.conf) tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1660/mysqld tcp 0 0 0.0.0.0:842 0.0.0.0:* LISTEN 1317/inetd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 13938/nginx
这意味着端口80正在监听服务器本地的所有接口。 如果另一个进程在我的nginx
服务器启动之前持有端口80,那么nginx
将无法控制该端口,并且可能会失败其启动过程。
通常情况下,端口3306是好的,因为侦听服务具有从主机请求的预定义的端口(或范围) – 例如用于web服务器的端口80和443。