负载均衡器会根据它运行的平台对它可以同时使用多少个 tcp 端口有一些限制(例如,我在某处读到 Linux 可以同时打开最多 65535 个 tcp 端口)。这意味着即使后端服务器场能够同时处理更多请求,平衡器也会成为瓶颈,并且无法提供超出这些同时请求的服务。有没有办法克服这个问题?
1 回答
TCP 和 UDP 端口号是 16 位的,因此给定的 IP 只有 65535 个(我相信端口 0 无效)。但是 TCP 连接由 4 元组(源 IP、源端口、目标 IP、目标端口)标识。(看起来维基百科有链接可以了解更多信息。)
对于客户端->平衡器请求:只要每个入站连接具有不同的(源 IP、源端口),就没有问题。客户通常会确保这一点。我记得听说过的唯一问题是一个非常受欢迎的网站,当从巨大的 ISP 访问时,每页有很多图像,这些 ISP 对他们的客户进行了 NAT,只在很少的 IPv4 地址后面。那可能不是你的情况。
balancer->backend 请求更有趣,因为您可能正在创建与我上面提到的 NAT 问题类似的情况。我认为 Linux 通常会尝试为每个套接字分配一个不同的临时端口,默认情况下只有 28,233 个。而且 IIRC 它也不使用该TIME_WAIT
州的连接,因此您可以用尽范围而无需同时打开那么多连接。IIRC,如果您达到此限制,您将EADDRINUSE
失败connect
(或者bind
如果您在连接之前明确绑定套接字)。我不记得我之前是如何解决这个问题的,更不用说绝对最好的方法了,但这里有一些可能会有所帮助的事情:
- 保持持久的平衡器->后端连接,而不是为每个(可能是短暂的)客户端->平衡器连接创建一个新连接。
- 在/之前设置
SO_REUSEADDR
套接字。bind
connect
- 打开 sysctl
net.ipv4.tcp_tw_reuse
和/或net.ipv4.tcp_tw_recycle
. - 明确选择要使用的源 IP 和/或端口,
bind
而不是让内核自动分配connect
. 您不能同时使用相同的 4 元组进行两个连接,但其他任何事情都可以。(例外:我正在考虑TIME_WAIT
重用同一个 4 元组是否可以;我必须TIME_WAIT
通过阅读一些 TCP RFC 来刷新我的记忆。)
你可能需要做一些实验。好消息是,一旦您了解了问题,就很容易重现并测试您是否已修复它。