网络繁忙时的极高延迟,TCP,libevent

时间:2017-01-11 16:30:44

标签: networking tcp server latency libevent

在我们基于C / S的在线游戏项目中,我们使用TCP进行网络传输。我们包括 Libevent ,利用bufferevent为每个连接自动处理网络I / O.

之前运作良好,但最近出现滞后问题。当我做一些压力测试以使网络更繁忙时,延迟变得非常高,几秒或更长。服务器陷入混乱状态:

  • 平均CPU使用率下降(0%-60%-0%-60%重复,等待什么?)
  • 净流量减少(nethogs)
  • 连接到服务器的客户端仍处于活动状态(netstat& tcpdump)

看起来神奇地降低了所有系统的速度,但与服务器的新连接响应及时退出。

当我将协议更改为UDP时,它在相同的情况下运行良好:没有明显的延迟,系统运行速度很快。净流量约为3M / S.

该项目正在Intranet上运行。我还测试了最高下载速度,接近18M / S.

我研究了Libevent的头文件和文件的一部分,试图为所有连接设置速率限制。它做了一些改进,但即使我尝试了几种不同的配置,也没有完全解决问题。这是我的参数:read_rate 163840,read_burst 163840,write_rate 163840,write_burst 163840,tick_len 500ms。

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

TCP =传输控制协议。它通过在延迟之后重传未确认的数据包来响应数据包丢失。在重复丢失的情况下,它会以指数方式退出。看一下尝试打开与没有响应的主机的连接的网络捕获:

enter image description here

它发送初始SYN,然后在没有获得1秒的确认后再次尝试。在没有获得确认后,它会在~2s之后发送另一个,然后是~4s,然后是~8s,依此类推。因此,您可以看到,在重复丢包时,您可能会遇到严重的延迟。

既然你说你故意强调网络,并且CPU使用率不一致,一种可能的解释是TCP正在等待重传丢失的数据包。

了解正在发生的事情的最佳方式是获取实际传输内容的网络捕获。如果你的主机连接到一个交换机,你可以" span"您可以进行捕获的另一个主机端口的感兴趣端口。

如果您的交换机不具备此功能,或者您没有对交换机进行管理控制,那么您必须从在线游戏中涉及的主机之一获取捕获。这样做的缺点是,捕获可能会改变发生的情况,并且它不会看到线路上的实际内容。例如,您可能为您的接口启用了TCP分段卸载,在这种情况下,捕获将看到将由网络接口​​分解的大型数据包。

我建议安装wireshark来分析网络捕获(你可以通过使用wireshark进行捕获来实时进行)。每当您使用联网系统时,我都会建议您使用wireshark,以便您可以了解网络上实际发生的情况。我建议您使用的第一个过滤器是tcp.analysis.flags,它会向您显示提示存在问题的数据包。

我还建议首先关闭速率限制以尝试查看正在发生的事情(速率限制是添加另一个不发送数据包的原因,这可能会使诊断更加困难到底是怎么回事)。此外,500毫秒可能是一个很长的tick_len取决于你的游戏如何运作。如果您的突发配置允许速率在100ms内用完,您将最终等待400ms才能再次传输。在这方面,IO Graph是Wireshark非常有用的功能。虽然默认的滴答间隔和单位在这方面不是很有用,但它可以帮助您查看传输速率。以下是突发流量限制为200mbit / s的示例:

enter image description here

请注意,滴答间隔为1毫秒,单位为位/滴答,这使得图表的顶部为1gb / s,即相关接口的速度。