我们遇到了一些奇怪的数据包丢失,想知道其原因。
我们有一个图像服务器和一个用于强调图像服务器的服务器。两者都位于同一个数据中心
首先,我们运行这样的负载测试(为便于阅读,命令已缩短):
ab -n 50 -c 5 http://testserver/img/de.png
该图像只有大约300字节。结果响应非常快:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 0
Processing: 1 3 0.7 3 4
Waiting: 1 3 0.7 3 3
Total: 1 3 0.7 3 4
当我们增加并发性时,我们会看到一些滞后(为便于阅读,命令已缩短):
sudo ab -n 500 -c 50 http://testserver/img/de.png
并发 50 的结果:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 1
Processing: 2 35 101.6 12 614
Waiting: 2 35 101.6 12 614
Total: 3 36 101.7 12 615
所以我们看到大多数请求都非常快,但其中有一些请求非常慢。
我们用 tcpdump 转储了整个网络流量,发现一些奇怪的重传。
替代文本 http://vygen.de/screenshot1.png
此转储是在图像服务器上进行的!
因此,您会看到包含 GET 请求的初始包(编号 306)已到达图像服务器,但似乎在 tcpdump 记录该包后,该包丢失了。在我看来,这个包并没有到达 tomcat 图像服务器。
200 毫秒后,请求服务器触发重传,之后一切运行正常。
您知道为什么包裹在收到后会丢失吗?
我们的机器均具有:
- 英特尔(R) 酷睿(TM) i7 CPU 920 @ 2.67GHz
- 8 GB 内存
- 以太网控制器:Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express 千兆以太网控制器 (rev 02)
- Debian 版本 5.0.5
因此我们没有遇到任何有关内存或 CPU 负载的问题。
不久前,我们的网卡控制器出现了一些问题。我们通过使用不同的驱动程序解决了这个问题,现在我们使用 r8168 而不是 r8169
但我们在使用英特尔网卡时也遇到了同样的数据包丢失问题 - 以太网控制器:英特尔公司 82541PI 千兆以太网控制器(修订版 05)
因此,我们在同样的机器但不同的以太网卡上看到了同样的问题。
到目前为止,我认为数据包丢失只会发生在线的服务器之间,当数据包损坏或类似情况时。
我们确实想知道 tcpdump 记录这些数据包后,这些数据包丢失的原因可能是什么。
非常感谢您的帮助。
答案1
我们找到了问题的根本原因。我们的 tomcat server.xml 中的 acceptCount 为 25。
acceptCount 的记录如下:
接受计数
当所有可能的请求处理线程都在使用时,传入连接请求的最大队列长度。队列已满时收到的任何请求都将被拒绝。默认值为 100。
但这并不是关于 acceptCount 的全部内容。简而言之:acceptCount 是打开套接字时的 backlog 参数。因此,即使并非所有线程都处于繁忙状态,此值对于监听 backlog 也很重要。如果请求以更快的速度进入,则 tomcat 可以接受它们并将其委托给等待线程,这一点很重要。默认的 acceptCount 为 100。这仍然是一个很小的值,无法满足请求的突然高峰。
我们用 apache 和 nginx 检查了同样的情况,也出现了奇怪的丢包现象,但并发值更高。apache 中的对应值是 ListenBacklog,默认值为 511。
但是,在 debian(和其他基于 Linux 的操作系统)中,backlog 参数的默认最大值是 128。
$ sysctl -a | grep somaxc
net.core.somaxconn = 128
因此,无论您输入 acceptCount 还是 ListenBacklog,它都不会超过 128,除非您更改 net.core.somaxconn
对于非常繁忙的 Web 服务器,128 是不够的。您应该根据需要将其更改为 500、1000 或 3000。
将 acceptCount 设置为 1000 并将 net.core.somaxconn 设置为 1000 后,我们不再有那些丢包的情况。(现在我们在其他地方遇到了瓶颈,但这是另一个故事……)
答案2
200ms 是默认的 TCP 重传超时 (RTO);在RFC2988,尽管没有定义该最小值)。
所以... 某些东西被延迟或丢失,导致 RTO 被触发。也许数据包被延迟,从而触发了 RTO,但 wireshark 在数据包解析/渲染过程中将其平滑了?您应该更详细地调查跟踪。
您可以提供一张更大的数据包捕获图像吗?