负载平衡Web套接字

Joh*_*ith 91 load-balancing server-push websocket

我有一个关于如何负载平衡Web套接字的问题.

我有一个支持Web套接字的服务器.浏览器连接到我的站点,每个浏览器打开一个Web套接字www.mydomain.com.这样,我的社交网络应用程序可以将消息推送到客户端.

传统上,只使用HTTP请求,我会通过在两个Web服务器前添加第二个服务器和负载均衡器来扩展.

使用Web套接字,连接必须直接与Web服务器,而不是负载平衡器,因为如果一台机器的物理限制为64k开放端口,并且客户端连接到负载均衡器,那么我无法支持超过64k并发用户.

那我该怎么办 -

  1. 让页面加载时客户端直接连接到Web服务器(而不是负载均衡器)?我是否只是从节点加载JavaScript,并且每次最初请求页面时,负载均衡器(或其他)会随机修改脚本的URL?

  2. 处理涟漪开始?当Web服务器关闭时,浏览器会注意到连接已关闭.我可以编写JavaScript代码来尝试重新打开连接,但该节点将会消失一段时间.所以我想我必须回到负载均衡器来查询下一个要使用的节点的地址?

  3. 我确实想知道负载均衡器在初始请求上发送重定向,以便浏览器最初请求www.mydomain.com并重定向到www34.mydomain.com.这很有效,直到节点出现故障 - 像Facebook这样的网站不这样做.他们是如何做到的呢?

obe*_*tet 77

放置一个L3负载均衡器,将基​​于源IP地址哈希的IP数据包分发到您的WebSocket服务器场.由于L3平衡器不维持状态(使用散列源-IP端口),因此它将在低端硬件(例如10GbE)上扩展到线速.由于分布是确定性的(使用散列源-IP端口),因此它将与TCP(以及因此WebSocket)一起使用.

另请注意,64k硬限制仅适用于给定(源)IP地址的传出 TCP/IP.它不适用于传入的TCP/IP.我们测试了Autobahn(高性能WebSocket服务器),在2核4GB RAM VM上有200k活动连接.

另请注意,您可以在初始WebSocket握手期间宣布的HTTP路径上执行L7负载平衡.在这种情况下,负载均衡器必须维持状态(哪个源IP端口对将进入哪个后端节点).尽管如此,它可能会扩展到数百万个连接.

免责声明:我是Autobahn的原作者,也为Tavendo工作.

  • 是的,只有 1 个 URL,后者的主机名应该解析为您的负载平衡器。WebSocket 后端服务器具有内部 IP(非公共 IP),并且可以选择在与公共 IP 不同的端口上运行。唯一需要注意的是,您可能需要告诉 WebSocket 服务器它们的公共可见主机名、IP、端口是什么,因为符合 WebSocket 服务器将检查 WS 握手的 HTTP 标头中提供的 URL 是否适合它们的主机名/IP/端口正在听。 (2认同)
  • 在我描述的方法中,LB 上没有 TCP 状态,因为它是 L3/4 LB。它只是 IP 数据包,LB 上保留的唯一状态是后端服务器的运行状况以及对这些数据包的一致哈希。Rgd 返回流量:DSR(直接服务器返回)当然也是可能的。这是后端服务器的一个功能。无论如何,不​​要担心 LB 性能……不是 L4,甚至是现在的 L7。现代 LB 可以使用 L2 功能进行扩展.. 对于 99% 的用户来说这不是问题(除非您需要 10 mio 并发活动 websocket 连接) (2认同)

小智 9

请注意,如果您的 websocket 服务器逻辑在带有 socket.io 的 Nodejs 上运行,您可以告诉 socket.io 使用共享的 Redis 键/值存储进行同步。这样您甚至不必关心负载均衡器,事件将在服务器实例之间传播。

var io = require('socket.io')(3000);
var redis = require('socket.io-redis'); 
io.adapter(redis({ host: 'localhost', port: 6379 }));
Run Code Online (Sandbox Code Playgroud)

请参阅:Socket IO - 使用多个节点

但在某些时候,我猜 Redis 可能会成为瓶颈......