TCP 零窗口大小和全窗口大小

TCP 零窗口大小和全窗口大小

我们面临的问题是,一些 http 连接的响应时间 > 60 秒(约 5%)。我发现问题应该出在 Web 服务器和负载均衡器之间。

这是我的发现,我们尝试了两组服务器:

设置 A:只有 1 个 Web 服务器(服务器 A),所有 tcp 流量都直接指向该服务器。

设置 B:负载均衡器 + 服务器 A,服务器 A 的权重为 100。采用“使用持久 IP 的循环调度”算法

对于设置A,tcp连接非常稳定,超时率小于1%。但是对于设置B,超时率超过5%,这就是问题所在。(客户端设置的连接超时为60秒)

我们在普通环境下(10 分钟内)测试了这两种设置,数据包数量(约 700,000 个数据包)和流量非常接近。结果,我们得到了 2 组 tcpdump,我发现了一些奇怪的日志条目,并对其进行了统计,如下所示:

                            Setup A                Setup B
TCP Zero window size        0                      611
TCP Window Full             0                      3672
TCP Out-Of-Order            4147                   4577
TCP Retransmission          23665                  21551
TCP Dup Ack                 10592                  10121

对于上述结果,我很确定这个问题与 TCP 窗口有关,所以我尝试启用 net.ipv4.tcp_window_scaling > 重新启动,但这没有帮助。我也试过禁用 iptables,也没有帮助。我不知道是否有任何配置影响 TCP 窗口。

值得知道的一件事是,我们的负载均衡器 IP 是 xx.xx.117.128,所有标记为 TCP 窗口满的数据包都从服务器 A 到 xx.xx.117.25,所有标记为 TCP 零窗口大小的数据包都从 xx.xx.117.25 到服务器 A

我问过 softlayer 技术人员 xx.xx.117.25 是什么,他们说“xx.xx.117.25 是负载平衡器连接到真实服务器的地址”他们猜测这是防火墙问题,正如我上面提到的,我已经在关闭 iptables 的情况下进行了测试。因此我们可以排除这个因素

这就是我迄今为止发现的。

也许您对 sysctl 配置感兴趣,它位于以下位置:

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
kernel.shmall = 4294967296
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_window_scaling = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_max_syn_backlog = 1000
net.core.netdev_max_backlog = 1000
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_fin_timeout = 20

以下是设置 A 中服务器 A 的 TCP 状态快照

604 TIME_WAIT
7 SYN_RECV
1 LISTEN
2 FIN_WAIT1
1 ESTABLISHED
1 CLOSING

不太清楚为什么 TIME_WAIT 这么高(我已经启用了 tcp_tw_reuse 和 tcp_tw_recycle)我也监控了设置 B 上的 tcp 状态,TIME_WAIT 的数量甚至更少(大约 300 - 400)

对于 apache 配置:

KeepAlive Off
<IfModule prefork.c>
StartServers       5
MinSpareServers   10
MaxSpareServers   50
ServerLimit      500
MaxClients       500
MaxRequestsPerChild  4000
</IfModule>

请帮忙。非常感谢

答案1

您是否尝试过不使用tcp_tw_recycletcp_tw_reuse选项进行设置?至少tcp_tw_recycle会导致负载平衡器出现问题。

此外,状态下的套接字数量TIME_WAIT不应该成为问题,因为它远不及 30k,这是 Linux 中可用端口的默认数量。

如果您想确保有足够的可用端口,可以将net.ipv4.ip_local_port_rangesysctl 设置为1024 65535

相关内容