【问题标题】:At what point are WebSockets less efficient than Polling?WebSockets 在什么时候比轮询效率低?
【发布时间】:2017-11-27 14:48:24
【问题描述】:

虽然我知道上述问题的答案在某种程度上取决于您的应用程序架构,但我主要对非常简单的场景感兴趣。

基本上,如果我的应用每 5 秒或每分钟 ping 一次以进行更改,那么大约何时发送以维持打开的 Web Sockets 连接的数据最终会超过您通过简单轮询所浪费的数量?

基本上,如果应用程序不一定需要实时更新,而只需要定期检查,是否有一种方法可以量化使用 Meteor 等框架会导致多少低效率。

请注意,我的重点是带宽利用率,不一定是数据库访问时间,因为像 Meteor 这样的框架具有高度优化的方法,只请求更新数据库。

【问题讨论】:

    标签: performance optimization websocket polling


    【解决方案1】:

    我相信@jfriend00 非常清楚地回答了这个问题。不过,我确实想补充一点。

    通过将 Websockets 与 HTTP 放在最坏的情况(并且不太可能)的情况下,您会清楚地看到 Websocket 连接在带宽(并且可能是全方位的性能)方面始终具有优势。

    这是 Websockets v/s HTTP 的最坏情况:

    • 您的代码使用 Websocket 连接的方式与使用 HTTP 请求的方式完全相同,用于轮询。

      (我知道你不会这样做,但这是最坏的情况)。

    • 每个轮询事件都得到肯定回答 - 这意味着没有任何 HTTP 请求是徒劳的。

    对于 Websockets 来说这是最糟糕的情况,它设计用于推送数据而不是轮询......即使在这种情况下,Websockets 也会为您节省带宽和 CPU 周期。

    说真的,即使忽略 DNS 查询(由客户端执行,因此您可能不关心它)和 TCP/IP 握手(这对客户端和服务器来说都很昂贵),Websocket 连接仍然具有更高的性能并且具有成本效益。

    我会解释

    每个 HTTP 请求都包含大量数据,例如 cookie 和其他标头。在许多情况下,每个 HTTP 请求还需要经过客户端身份验证……很少会将数据泄露给任何人。

    这意味着 HTTP 连接传递所有这些数据(并可能执行客户端身份验证)每个请求一次。[无状态]

    但是,Websocket 连接是有状态的。数据只发送一次(而不是每次发出请求)。客户端身份验证仅在 Websocket 连接协商期间发生。

    这意味着 Websocket 连接传递相同的数据(并且可能执行客户端身份验证)每个连接一次(一次用于所有轮询)。

    因此,即使在这种最坏的情况下,轮询始终为正并且 Websocket 用于轮询而不是推送数据,Websocket 仍将节省您的服务器带宽和其他资源(即 CPU 时间)。

    简单地说,我认为您的问题的答案是“从不”。 Websocket 的效率永远不会低于轮询。

    【讨论】:

      【解决方案2】:

      websocket 连接的全部意义在于,您无需 ping 应用程序即可进行更改。相反,客户端只需连接一次,然后服务器可以在客户端可用时直接发送更改。客户永远不必问。服务器只在数据可用时发送数据。

      对于任何类型的服务器启动数据,这在带宽方面比 http 轮询更有效。除了为您提供更及时的结果(结果会立即交付,而不是仅在下一个轮询间隔由客户端发现)。

      对于纯带宽使用,详细信息将取决于具体情况。 http 轮询请求必须建立 TCP 连接并确认该连接(如果是 SSL 连接,则需要更多数据),然后它必须发送 http 请求,包括属于该主机的任何相关 cookie,包括相关标头和获取网址。然后,服务器必须发送响应。而且,在大多数情况下,所有这些轮询开销都将完全浪费带宽,因为没有什么新内容要报告。

      一个 webSocket 从一个简单的 http 请求开始,然后将协议升级为 webSocket 协议。 webSocket 连接本身根本不需要发送任何数据,直到服务器有东西要发送给客户端,在这种情况下,服务器只发送数据包。发送数据本身的开销也少得多。没有cookies,没有标题等……只有数据。即使您在 webSocket 上使用了一些 keep-alives,与 HTTP 请求的开销相比,该数据量也非常小。

      因此,您将节省多少带宽取决于具体情况。如果它需要 50 个轮询请求才能找到任何有用的数据,那么与 webSocket 场景相比,这些 http 请求中的每一个都是完全浪费的。带宽差异可能很大。

      您询问了只需要定期检查的应用程序。一旦您进行了定期检查而没有检索到任何数据,这就是浪费带宽。这就是 webSocket 的全部想法。当没有数据要发送时,您不会消耗带宽(或几乎没有带宽)。

      【讨论】:

      • 维护一个开放的 WebSocket 需要多少带宽?我假设在服务器想要将任何内容推送到客户端时,必须至少偶尔将数据包从客户端发送到服务器,以便启用 NAT 穿越。
      • @Eckster - NAT 实现将根据它们对非活动 TCP 连接的作用而有所不同。 webSockets 可以选择发送 ping/pong 数据包。它们是非常小的数据包(以字节为单位,在我看来它像 2 个字节的实际数据加上 TCP 开销),因此这不太可能对整体带宽使用有很大贡献。在有数十万个 webSocket 连接到服务器的情况下,keep alives 可能更多地表现在处理能力上,每个连接都偶尔会出现 ping/pong。
      • 但是服务器资源会发生什么?每 5 秒处理一次请求不是比为每个用户永久保持连接更好吗?
      • @Enrique - 空闲套接字不会占用大量服务器资源 - 实际上只占用系统内存。如今,经过适当定制的服务器可以配置为同时处理一百万个套接字。如果你在 webSockets 和 http 轮询之间做出决定,你真的必须将一个使用场景放在一起,说明有多少并发客户端和可接受的轮询间隔,以及客户端实际有新数据的频率,然后你可以开始建模哪个会更有效率。魔鬼在细节中。
      • @Enrique - 一方面,如果客户端只打算每 30 分钟轮询一次,那么 http 请求可能是正确的处理方式,但如果客户端需要低延迟对于服务器端的更改(比如几秒钟内),那么在服务器上使用 http 轮询将比 webSocket 更难。 http 长轮询也是一种介于两者之间的解决方案,但通常被 webSockets 取代。
      猜你喜欢
      • 1970-01-01
      • 2015-09-04
      • 2013-05-20
      • 2015-06-15
      • 1970-01-01
      • 2022-01-21
      • 2017-05-27
      • 2012-06-18
      • 1970-01-01
      相关资源
      最近更新 更多