长期投票的严重缺点?

对于交互式Web应用程序,像Websockets这样的东西越来越受欢迎。 然而,由于客户端和代理世界并不总是完全兼容,所以通常会使用像“Socket.IO”这样的复杂框架,对于任何可能会禁用其他框架的情况隐藏几种不同的机制。

我只是想知道一个正确实现的长轮询的缺点是什么,因为今天的服务器比如node.js很容易实现,并依赖于很好的支持旧的http技术(尽pipe长时间的轮询行为本身可能会打破它)。

从高层次来看,长时间轮询(尽pipe有一些额外的开销,适用于中等stream量的应用程序)类似于WebSockets所做的真正的推送行为,因为服务器每当他喜欢(尽pipe有一些超时/心跳机制)实际发送它的答案。

所以我们有更多的开销,因为我猜测TCP / IP更多的确认,但没有像频繁轮询那样的持续stream量。

而使用事件驱动的服务器,我们将不会有线程开销来阻止连接。

那么是否还有其他困难的缺点,迫使像聊天这样的中等stream量应用使用WebSockets而不是长时间轮询?

高架

它会每次创build一个新的连接,所以它会发送HTTP头……包括可能很大的cookie头。

另外,只是“检查是否有新的东西”是另一个没有任何联系。 连接意味着诸如防火墙,负载均衡器,Web服务器等许多项目的工作。或许,build立连接是您IT基础架构有多个检查员的最耗时的事情。

如果您使用的是HTTPS,则您正在做一次又一次最昂贵的操作,即TLS握手。 一旦build立连接并且对称encryption正在工作,TLS性能是好的,但build立连接,密钥交换和所有爵士的过程并不快。

另外,当连接完成时,日志条目被写入某个地方,计数器在某处增加,内存被消耗,对象被创build…等等。例如,我们之所以在生产中有不同的日志configuration,在开发中,是因为写日志条目也会影响性能。

存在

长轮询用户何时连接或断开连接? 如果你在给定的时间检查这个…你需要等待多长时间才能再次检查,以确保它已断开或连接?

如果你的应用程序只是播放的东西,这可能是完全不相关的,但如果你的应用程序是一个游戏,这可能是非常相关的。

不坚持

这是个大问题。

由于每次都创build一个新的连接,如果你有负载均衡的服务器,在一个循环的robbin场景中,你不能知道下一个连接将在哪个服务器上下降。

当用户的服务器是已知的,就像使用WebSocket一样,你可以直接将事件推送到服务器,服务器将它们中继到连接。 如果用户断开,服务器可以立即通知用户没有连接,再次连接时可以再次订阅。

如果用户在生成事件时连接的服务器是未知的,则必须等待用户连接,那么你可以说:“嗨,用户123在这里,给我所有的消息,因为这个时间戳“,是什么让它更麻烦一点。 长轮询并不是真正的推技术,而是请求响应,所以如果你计划采用EDA架构,那么在某些时候你将要有一定的阻抗级别,比如你需要一个事件聚合器给你所有事件从一个给定的时间戳(最后一次用户连接请求消息)。

SignalR(我猜这是相当于.NET的socket.io),例如,有一个名为底板的消息总线,将所有消息中继到所有服务器,作为扩展的关键。 因此,当用户连接到其他服务器时,“他的”待处理事件也存在“(!)这是一个”不错的方法“,但正如您猜测的那样,会影响吞吐量:

限制

使用背板时,最大消息吞吐量低于客户端直接与单个服务器节点通话时的吞吐量。 这是因为背板将每条消息转发给每个节点,所以背板可能成为瓶颈。 这个限制是否是一个问题取决于应用程序。 例如,以下是一些典型的SignalRscheme:

  • 服务器广播(例如股票行情):这种情况下,背板运行良好,因为服务器控制着发送消息的速率。

  • 客户端到客户端(例如,聊天):在这种情况下,如果消息数与客户端数量成比例,则背板可能是瓶颈 ; 也就是说,如果消息的比例随着更多的客户join而成比例地增长。

  • 高频实时(如实时游戏):不推荐在这种情况下使用背板。

对于一些项目来说,这可能是一个不争的事实。

一些应用程序只是广播一般数据,而另一些应用程序则具有连接语义,例如多人游戏,将正确的事件发送到正确的连接是非常重要的。

恕我直言

长时间轮询对于小型项目来说是一个很好的解决scheme,但是对于那些需要高频率和/或非常细分的事件发送的高度可扩展的应用程序来说,它成为了一个很大的负担。