【问题标题】:What is the cause of websocket latency spikes?websocket延迟峰值的原因是什么?
【发布时间】:2016-08-03 19:14:48
【问题描述】:

我在单个 AWS 实例上运行服务器(使用 tornado python),并且遇到了 websocket 延迟峰值。

分析从将 websocket 消息发送到客户端(然后客户端立即将 ack 消息发送回服务器)到服务器接收到 ack 消息的往返时间平均为 <.1>

这可能是什么原因或解决方法?我查看了 CPU 使用率,它最多只能达到 40%。峰值与大量流量(通常是 2 或 3 个客户端)无关,并且客户端的互联网似乎很好。我很难相信实例在如此低的使用率下会超出容量。

【问题讨论】:

    标签: amazon-web-services websocket tornado


    【解决方案1】:

    峰值为 3 秒这一事实实际上比您想象的更多地告诉您问题的性质。

    这是丢包。

    您可能知道,TCP 被称为提供“可靠”传输,保证发送的有效负载按照发送的顺序被远端接收,因为 TCP 在发送有效负载之前以正确的顺序重新组装事物.实现这一点的一种重要方法是自动重新传输被认为已丢失的数据包。

    您永远猜不到重新传输丢失数据包的默认初始计时器值。或者,也许,现在,你会的。

    根据几年前制定的标准,在许多(如果不是大多数)实施中,它是 3 秒,当时当今传输链路的带宽和延迟是闻所未闻的,也许是无法想象的。

    您不会在 websocket 服务器或客户端软件上看到重新传输的证据,因为 TCP 会屏蔽更高层,使其不知道它发生了......但是 3 秒是一个死的赠品,这正是问题所在。

    如果您使用数据包嗅探器观察网络流量,您会看到重新传输的流量,但这仅用于确认这是问题所在。

    它可能是从服务器到客户端的丢失,或者从客户端到服务器的丢失。后者通常更有可能,因为客户端通常具有较少量的可用上行带宽......但是数据包丢失的方向性并不能清楚地表明它发生的物理位置。除非您的客户端跟踪本地时间,以便可以关联请求和响应启动时间,否则您不知道延迟是在消息中还是在确认中。

    在相对较轻的负载下,问题似乎不太可能出在您的实例或您身边的 AWS 网络中,而且您显然无法将嗅探器连接到 Internet 上的任意点来查明问题。

    鉴于这样的情况,证明问题不是的位置,而不是的位置可能更容易——而且令人惊讶地可行。

    为此,一种技术是通过位于其他地方的不同设备(例如不同的 AWS 区域或其他云提供商)故意绕道。

    首先,当然,您需要学习使用wireshark 发现这些重传。

    然后,在不同的位置配置代理服务器,使用简单的 TCP 连接代理 - 例如 HAProxy,甚至是像 redirsocat 这样的简单工具。

    这样的配置会监听来自客户端的连接,当一个连接建立后,会创建一个到目的地(你的 websocket 服务器)的新 TCP 连接,但是——重要的是——它们只在有效负载级别将两个连接绑定在一起-- 不是 TCP 级别,当然也没有更低的级别 -- 所以重传只会出现在这个中间服务器和连接结束之间的线路上,并存在丢包问题。另一端不会显示重传的证据——只是数据到达的时间比预期的晚。

    为了使这个测试有意义,代理需要远离服务器和客户端,并且没有有意义的公共基础设施——因此建议将其放置在不同的 AWS 区域。同一区域中的不同可用区可能会在一定程度上共享公共互联网基础设施,因此距离远不足以实现此目的。

    如果client &lt;--&gt; proxy &lt;--&gt; server 在代理和服务器之间的路径上显示 TCP 重新传输,而不是在客户端和代理之间,那么问题很可能出在您的服务器、它的硬件、网络或 Internet 连接上,您将遇到进行相应的操作。

    相反(我建议,更有可能)如果代理和服务器之间的路径没有重传,但客户端和代理之间的路径仍然很脏,那么您已经消除了服务器及其基础架构作为问题的根源.如何继续取决于您,但此时您确实知道问题所在......不是。

    另外两种可能性:

    双方仍然脏,这是最不可能的情况。故障排除的规则 1 是最初假设您只有一个问题,而不是两个。

    或者,当流量使用此设置时,双方突然且不经意地干净,这表明您的测试设置已绕过 Internet 的一个损坏部分。您已经“解决”了它,但不知道如何解决。我们也希望这不是结果,但考虑到全球互联网的变幻莫测,您的堆栈可能包含这样的组件并不是不可想象的,其中包含基于地理位置-DNS 的中间端点选择。这看起来像一个卷积,但确实有它的位置。

    这种策略实际上是S3 transfer acceleration 功能背后逻辑的一部分。内容不再靠近最终用户,但是来自浏览器的 TCP 连接正在 AWS 边缘网络中的设备上终止,该位置通常更靠近浏览器,并且返回到存储桶的第二个 TCP 连接是建立,有效载荷连接在一起......而且,是的,它更快,更稳定,随着距离和连接质量的变化,变化的重要性变得更加明显。

    【讨论】:

    • 我尝试通过使用wireshark观察流量来验证丢包,但我无法确认。当我没有来自客户端的任何延迟时,我可以观察到丢包帧,尽管我无法始终如一地重现延迟,但我无法找到与丢包帧相关的任何延迟。我也很好奇其他 websockets 服务器如何处理数据包丢失,因为它们似乎可以扩展到更多的用户仍然保持响应。
    • 您不想在这里混淆两个问题。丢包肯定会伴随流量增加,但目前没有理由相信您遇到的问题与服务器负载有关,也没有理由相信它在规模上必然会更糟。您可以扩展您的代码,以便客户端从其本地时钟发送时间吗?建立偏移量后,了解错误的方向性会很有趣,而且您似乎需要一个客户端时间戳。如果您想尝试中间人测试,请查看我的 SO 个人资料以获取联系信息。
    • 我在从客户端发送时间戳时遇到问题,因为它会发送本地机器的时间,与服务器时间戳相比我无法考虑
    • 是的,您可以...只要您计算并记住两者之间的偏移量。如果我的时钟似乎比你的时钟早 5 分钟,然后是 5 分钟,然后是 5 分钟,然后突然是 4 分 57 秒,那么你知道延迟是从我到你,因为我一定看过我的时钟在你“听到”我告诉你“当前”时间之前 3 秒。如果从您的角度来看,我的时钟偏移从未改变,即使您有时会看到延迟响应,那么延迟是 从您到我,因为我在听到您的声音之前不会看时钟问我,您会立即收到我的答复。
    • 我运行了一个配置文件并计算了客户端接收到消息的时间减去从服务器发送消息的时间,记录的时间大多少于 1 秒到超过 3 秒。这使我相信延迟来自服务器(否则延迟服务器-> 客户端应该是〜常量,而 rtt 尖峰将是客户端-> 服务器)。如果我的想法是正确的,一种方法是如何修复服务器?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 1970-01-01
    • 2021-06-23
    • 2021-10-30
    • 2019-09-08
    • 1970-01-01
    相关资源
    最近更新 更多