123

我有一个关于如何负载平衡网络套接字的问题。

我有一个支持 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 这样的网站不会这样做。他们是怎么做到的呢?

4

3 回答 3

111

将基于源 IP 端口哈希分配 IP 数据包的 L3 负载平衡器放置到您的 WebSocket 服务器场。由于 L3 平衡器不维护任何状态(使用散列源 IP 端口),它将扩展到低端硬件(例如 10GbE)上的线速。由于分布是确定性的(使用散列的源 IP 端口),它将与 TCP(以及 WebSocket)一起使用。

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

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

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

于 2012-09-21T08:27:36.553 回答
5

请注意,如果您的 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 }));

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

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

于 2016-08-31T13:14:39.787 回答
2

您还可以通过检查和“路由功能”实现第 7 层负载平衡

请参阅“如何使用 Stingray 流量管理器检查和负载平衡 WebSocket 流量,以及在必要时如何管理在同一 IP 地址和端口上接收的 WebSocket 和 HTTP 流量。” https://splash.riverbed.com/docs/DOC-1451

于 2013-10-21T16:44:29.767 回答