我正在一个AWS实例上运行一个服务器(使用tornado python),而且我遇到了websocket延迟的峰值。
分析从将websocket消息发送到客户端的往返时间,然后立即将ack消息发送回服务器,到服务器接收到ack消息时产生平均<.1秒,但是我注意到它有时会持续3秒钟。注意:在本地运行服务器时没有峰值。
可能是什么原因或解决方法?我查看了CPU的使用情况,最多只能达到40%。尖峰与繁忙的交通(通常是2或3个客户)无关,客户的互联网似乎很好。我发现很难相信这个实例超出了使用率如此之低的容量。
答案 0 :(得分:3)
飙升3秒的事实实际上告诉了你比你可能怀疑的更多,关于问题的本质。
它的丢包。
正如您所知,TCP据说可以提供可靠的&#34;传输,保证发送的有效载荷由远端按发送顺序接收,因为TCP在传送有效载荷之前以正确的顺序重新组装。实现这一目标的一个重要方法是自动重传被认为已丢失的数据包。您永远不会猜测重新丢失数据包的默认初始计时器值。或者,或许,现在,你会。
在许多(如果不是大多数)实施方案中,基于几年前建立的标准,在今天的传输链路的带宽和延迟闻所未闻,可能无法想象的情况下,这是3秒。
你不会在websocket服务器或客户端软件上看到转发的证据,因为TCP保护较高层免于知道它发生...但3秒是一个死的赠品,这正是问题
如果您通过数据包嗅探器观察网络流量,您将看到流量的重新传输,但这只会确认这是问题所在。
从服务器到客户端可能会丢失,或者从客户端丢失到服务器。后者通常更有可能,因为客户端通常具有较低的可用上游带宽量......但是丢包的方向性并不能清楚地指示其发生的物理位置。除非您的客户跟踪当地时间,以便请求和响应启动时间可以相关,否则您不知道延迟是在消息中还是在确认中。
在相对较轻的负载下,问题似乎不太可能出现在您的实例或您身边的AWS网络中,并且您显然无法将嗅探器连接到Internet上的任意点以查明问题。< / p>
鉴于这样的情况,可能更容易 - 并且令人惊讶地可行 - 证明问题不是的位置,而不是 的位置
其中一种技术是通过位于其他地方的不同设备(例如不同的AWS区域或其他云提供商)为流量创建故意绕行。
首先,当然,您希望学习使用wireshark来发现这些重新传输。
然后,使用简单的TCP连接代理(例如HAProxy)或甚至像redir
或socat
这样的简单工具,在不同的位置配置代理服务器。
这样的配置将侦听来自客户端的连接,并且当建立一个连接时,将创建到目标(您的websocket服务器)的新TCP连接,但是 - 重要的是 - 它们仅在有效负载级别将两个连接绑定在一起 - 不是TCP级别,当然也没有更低 - 所以只有在这个中间服务器和带有丢包问题的连接结束之间的线路上才能看到重传。另一端将不会显示重传的证据 - 只是数据到达的时间晚于预期。
要使此测试有意义,代理需要远离服务器和客户端,并且没有有意义的通用基础架构 - 因此建议将其放置在不同的AWS区域中。同一地区的不同可用区域可能在某个级别共享通用的互联网基础设施,因此距离不足以达到此目的。
如果client <--> proxy <--> server
在代理和服务器之间的路径上显示TCP重新传输,而不是在客户端和代理之间显示TCP重新传输,问题实际上可能出现在您的服务器,其硬件,网络或Internet连接中,而您&# 39;我必须相应地进行。
相反(并且,我建议,更有可能)如果代理和服务器之间的路径没有重新传输但客户端和代理之间的路径仍然很脏,那么您已经消除了服务器及其基础架构作为问题的根源。如何进行取决于你,但此时你确实知道问题是什么......不是。
另外两种可能性:
双方都很肮脏,这是最不可能出现的情况。故障排除规则1首先假设您只有一个问题,而不是两个问题。
或者,当交通使用此设置时,双方都突然且无法保持清洁,这表明您的测试设置已绕过断开的互联网。你已经解决了#34;它但不知道如何。我们也希望这不是结果,但考虑到全球互联网的变幻莫测,你的堆栈可能包含这样的组件并不是不可想象的,基于地理位置 - 基于DNS的选择中间终点。这似乎是一个卷积,但确实有它的位置。
这种策略实际上是S3 transfer acceleration功能背后逻辑的一部分。内容与最终用户没有任何关系,但是来自浏览器的TCP连接正在AWS边缘网络中的设备上终止,位于通常更靠近浏览器的位置,并且第二个TCP连接回到存储桶是建立起来,有效载荷连接在一起......并且,是的,它更快更稳定,随着距离和连接质量的变化,变化的重要性变得更加显着。