【问题标题】:Websocket scalability, broadcasting concernsWebsocket 可扩展性,广播问题
【发布时间】:2012-02-05 11:03:37
【问题描述】:

如果您有一个包含许多用户(和服务器)的复杂需求集,您的 websocket 基础设施(服务器[s])将如何扩展,尤其是广播?

当然,广播不是任何 websocket 规范的一部分,但它甚至存在于基本的聊天示例中(也就是 websocket 的 hello world)。

客户端(请求新数据)解决方案似乎仍然比服务器端(广播)解决方案更具可扩展性,具有 websockets 的低延迟和相对便宜的(http 无标头)性质。

编辑:

好的,只是想你想用 websocket 实现替换所有的 ajax 代码,这可能意味着在这么多不同的上下文中有这么多的连接。如果您想跟踪所有可能的广播场景,这会给您的系统增加巨大的复杂性。

低(网络/线程等)级别的实施建议也是问题的一部分,而不是解决方案,因为这意味着您必须编写与一般 http 服务器不同的特殊服务器。

此外,广播给表格带来了某种不能轻易扩展的状态性质。考虑添加更多服务器和负载平衡。

【问题讨论】:

    标签: scalability websocket


    【解决方案1】:

    扩展实时 Web 解决方案可能是一个复杂的问题,但像 Pusher(我为之工作的)这样的服务已经解决了,并且为 self hosted realtime web solutions 定义了最明确的解决方案 - PubSub paradigm 很好理解并且已经解决了很多次,为了解决这个问题,需要有一些状态(谁在订阅什么)。此范例用于广播您正在谈论的场景类型。

    构建实时网络技术时考虑到了大量的同时连接 - 许多都是从头开始的。如果您想创建一个可扩展的解决方案,您很可能会使用支持 WebSockets 的现有实时 Web 服务器,就像您不太可能决定实现自己的 HTTP 服务器一样,您不太可能想要实现自己的服务器它从头开始支持 WebSockets。

    专用实时网络服务器还允许您将应用程序逻辑与实时通信机制(关注点分离)分开。您的应用程序可能需要维护一些状态,但实时技术处理的是管理订阅和连接。如何实现应用程序和实时 Web 技术之间的通信取决于您,但经常使用消息队列,特别是 redis 在这个领域非常流行。

    HTTP 轮询在概念上可能更容易理解 - 您可以保持无状态,并且每个 HTTP 轮询请求都可以准确指定您要查找的内容。但这绝对意味着您需要更快地开始扩展(添加更多资源来处理负载)。

    WebSocket 轮询是我以前没有考虑过的事情,我认为我之前也没有在任何地方看到过它的建议;客户应该说“我已经为我的下一组数据做好了准备,这就是我想要的”这个想法很有趣。 WebSockets 通常已经从请求/响应范式中取得了飞跃,但在某些情况下,WebSockets 和使用它们的请求/响应效率的提高可能会带来一些好处。 SocketStream 应用程序框架可能值得一看,因为它可能是相关的;在初始应用程序加载后,所有通信都通过 WebSockets 执行,这意味着事件基本请求/响应功能使用 WebSockets。

    但是,由于我们谈论的是广播数据,我们需要回到 PubSub 范式,在这种范式中,拥有活跃订阅更有意义,当有新数据可用时,新数据会分发给这些活跃订阅(推送)。您的应用程序只需要知道是否有任何活动订阅,以便决定是否发布数据。这个问题已经解决了。

    【讨论】:

      【解决方案2】:

      websockets 的理念是您与每个客户端保持持久连接。当您要向每个客户发送新数据时,您已经知道所有客户是谁,所以您应该发送它。

      听起来您希望每个客户端不断向服务器发送请求以获取新数据。为什么?似乎这会浪费每个人的带宽,我不知道您为什么认为它会更具可扩展性。也许您可以为您的问题添加更多细节,例如您正在广播什么样的信息、频率、字节数、客户端数量等。

      为什么不将打开的 websocket 连接视为客户端对更多数据的长期请求?

      【讨论】:

      • 恕我直言,“了解所有客户是谁”在服务器端 websocket 开发中并不容易。您必须有效地跟踪上下文中的每个人,并且拥有多个服务器会使它变得更加复杂。 IMO,要求新数据更具可扩展性,因为您的服务器实现不必了解客户端,因此您可以轻松添加新服务器。再说一次,如果你把它保持得小一点,这并不是真的浪费带宽,你可以使用 http headerless websocket。
      • 无论您做什么,服务器都必须了解客户端,因为您必须保留打开的套接字列表。如果没有打开的套接字列表,您将无法侦听来自它们的传入数据(例如,您将不知道要传递给 selectepoll 函数的文件描述符列表)。我认为您还需要跟踪传入和传出数据的缓冲区。您不能只忘记打开的 TCP/IP 连接。由于无论如何您都在跟踪该列表,因此如果需要,将您自己的一些识别数据添加到该列表中应该不会太难。
      • 你几乎混合了会话和套接字的概念;如您所知,第一个是应用程序级别,后者是网络级别。在实践中,你不想走得那么深,我也不想。恕我直言,最好在应用程序级别考虑这个问题。
      • 试试 libevent。它将允许扩展您的 websocket 服务器。它使用 epoll 等底层事件通知机制,而无需为每个打开的连接占用大量空间。
      • @FilipeSantos,我更喜欢netty.io,它也是一个异步事件驱动的网络应用框架。我想我不清楚这个问题,所以我会更新问题。
      猜你喜欢
      • 2021-03-31
      • 2013-08-21
      • 2018-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多