【问题标题】:Loadbalancing web sockets负载平衡 websocket
【发布时间】:2012-09-13 14:59:19
【问题描述】:

我有一个关于如何对 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 这样的网站不会这样做。他们是怎么做到的?

【问题讨论】:

标签: websocket load-balancing server-push


【解决方案1】:

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

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

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

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

【讨论】:

  • 所以我会从负载均衡器 URL 加载我的 javascript 库,并在我用 javascript 创建 Web 套接字时提供负载均衡器 URL - 你的意思是它对浏览器是透明的?太酷了!
  • 是的,只有 1 个 URL,后者的主机名应该解析为您的负载均衡器。 WebSocket 后端服务器具有内部 IP(非公共 IP),并且可以选择在与公共端口不同的端口上运行。唯一需要注意的是,您可能需要告诉 WebSocket 服务器它们的公共可见主机名、IP、端口是什么,因为符合标准的 WebSocket 服务器将检查 WS 握手的 HTTP 标头中提供的 URL 是否适合它们的主机名/IP/端口正在收听。
  • 我没有很多 websocket 连接需要平衡,但我有很多流量,或者说连接很少。为简单起见,现在说一个连接如何平衡通过一个 Web 套接字连接的请求?
  • 你能告诉我流程是什么样子的吗?客户端和负载均衡器之间会有什么类型的连接?是TCP吗?Tf是的,那么它和直接与后端服务器一样好,因为TCP连接数有限制,负载均衡器无法处理这么多连接,它可能可以处理与后端节点相同数量的连接,那么它做了什么样的负载平衡,我不明白。请你解释一下?
  • 在我描述的方法中,LB 上没有 TCP 状态,因为它是 L3/4 LB。它只是 IP 数据包,唯一要保留在 LB 上的状态是关于后端服务器的健康状况以及对它们的一致哈希。 Rgd返回流量:DSR(直接服务器返回)当然也是可以的。这是您的后端服务器的一项功能。无论如何,不​​要担心 LB 性能 .. 现在不是 L4,甚至不是 L7。现代 LB 可以使用 L2 功能进行横向扩展 .. 这对 99% 的用户来说不是问题(除非您需要说 10 个 mio 并发活动 websocket 连接)
【解决方案2】:

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

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

【讨论】:

【解决方案3】:

请注意,如果您的 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 - Using multiple nodes

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-28
    • 2018-12-24
    • 2018-02-17
    • 2015-02-11
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    相关资源
    最近更新 更多