我目前正在使用 HAProxy 来平衡从客户端到我的 Erlang 应用服务器的 tcp 连接的负载。连接是持久的,这意味着在优化的服务器上我只能使用大约 64K 个客户端(我目前正在 m1.large EC2 实例上运行 HAProxy)。我的应用服务器设计为根据 TCP 连接数进行水平扩展。但让我担心的是,我需要与应用服务器数量相同的 HAProxy 服务器,因为这是 1:1 连接。目前有没有办法将 tcp 连接“代理”到应用服务器,以便一旦 HAProxy 将客户端发送到我的 Erlang 服务器,它就可以释放连接,准备为另一个客户端提供服务?有没有我可以阅读的论文或现有解决方案,这样我只需要担心我的应用服务器上的 64K 限制,而不用担心负载平衡服务器本身?
答案1
您为什么认为您只能支持 64K 个客户端?您应该能够支持更多客户端。限制因素不是端口数量,而是内存和 CPU 能力,它们限制了您同时可以打开的连接数量。检查:http://www.kegel.com/c10k.html它已经过时了,只需将其视为 c100k 或 c1M 问题即可。:-)
顺便说一下,haproxy 网站上有一篇关于负载平衡和 haproxy 架构的优秀文章: http://haproxy.1wt.eu/download/1.2/doc/architecture.txt
关于连接限制,这是一个理论上的限制,通常您不会达到该限制,因为在此之前您的资源就已经耗尽了。
“TCP 标准将唯一连接标识符设置为本地 IP 地址、本地 TCP 端口号、远程 IP 地址和远程 TCP 端口号的三元组。在您的示例中,本地数字都是固定的,因此大约有 2^32 个远程 IP(版本 4)地址和 2^16 个 TCP 端口号,或者大约有 281,474,976,710,656 个潜在的同时 TCP 连接(2^48,或 2.81 * 10^14,或 281 万亿)。”
答案2
介绍
64k 并发闲置的对于 HAProxy 和 Erlang 来说,连接数是微不足道的。
首先要做的是在 HAProxy 上启用统计页面. 对于监控和性能调整来说,它是必须的。
那么让我们来讨论一下限制。
操作系统连接限制
每个元组只能有一个连接client_IP:client_PORT:server_IP:server_PORT
。它来自内核中存储和检索连接的方式(即哈希表)。Linux 和 Windows 上也是如此。
我不同意 aseq 的观点。这根本不是一个理论极限。这是一个非常实际的极限,任何进行中等负载测试的人都可能达到这个极限。
假设您当前的设置中有 3 台计算机:
[Test Computer] [HAProxy Computer] [Erlang Computer]
(front) test_IP:????<------>haproxy_IP:80
(back) haproxy_IP:????<------>erlang_IP:80
所有 IP 都是固定的,Web 服务器端口也是固定的。这样就只剩下一个端口作为可变参数,因此最大连接数受任何一台计算机上可用端口数的限制。这里几乎没有余地(请参阅临时端口范围)。您必须获取更多实例,包括 Erlang 实例和负载测试实例。
笔记:请注意,用户自然来自大量 IP,而负载测试器(curl、Apache ab、JMeter)通常在具有单个 IP 的单个盒子上运行(JMeter 和类似工具可以使用分布式从属进行扩展)。
笔记:HAProxy 连接始终是成对的(一个连接到客户端 + 一个连接到内部服务器)。请记住这一点,因为大多数系统限制必须是 2*N 才能允许 N 个用户。
临时端口范围
仅有少数端口用于创建新连接。它们被称为ephemeral ports
。Linux 默认端口为 32768 至 61000。
扩大范围。首先检查您的服务器上是否有正在运行的服务使用它们。
sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 20000 65000
这项调整只能提供 60% 的端口。这不足以通过单个服务器实现网络规模。
短暂的港口
请注意,端口在关闭后一分钟内不能重新使用(请参阅 TCP 状态),这会使端口池变得非常小(例如 10k 端口/秒?)。有内核设置可以更改关闭持续时间并允许重新使用正在关闭的端口。
只要持久连接存在的时间足够长(至少在更新前几分钟),您就不需要进行这些调整。尽管如此,意识到潜在的问题仍然很重要。
HAProxy 最大连接数
在 HAProxy 中配置maxconn
设置。这是允许在任何时候打开的最大连接数。
可以在global
、 perfrontend
或 per中配置backend
。统计信息页面显示每项活动设置。
Linux ulimit
ulimit 是单个进程打开的最大文件数量(套接字是 Linux 上的文件)。Linux 默认值介于 1k 到 10k 之间。
HAProxy 根据该maxconn
参数自动配置其进程的 ulimit。
您可能需要为 Erlang 进程手动调整 ulimit。
答案3
我认为回答您的问题的最佳方式是指出您不需要 HAProxy 和应用服务器之间的 1:1 映射。通过多种方法可以使用 HAProxy 建立持久连接。我建议在文档中搜索“持久”以了解更多信息:http://haproxy.1wt.eu/download/1.4/doc/configuration.txt。
例如,仅使用 TCP 连接,添加平衡源您的配置应该为您提供持久性。
答案4
每台主机 64k 是一个明确的硬性限制,但处理该限制的应用服务器通常在此之前内存耗尽。通常,在 32 位虚拟机耗尽堆之前,Java 应用服务器会以 2000 个并发连接运行。