我对 TCP/IP 堆栈的了解有点生疏,所以请耐心等待......
我有一台装有 SendMail 的 CentOS 5.7 服务器,在向其他远程域发送电子邮件(尤其是较大的电子邮件)时,我遇到了间歇性超时问题。并非所有附件或收件人域都会发生这种情况。只有一些。经过一些扩展的故障排除后,我认为我已经将问题缩小到 TCP 序列未被确认。
以下是我直接在 MTA(fooMTA)上收集的数据包捕获的 TCP 会话细目:
Packet 1 - 11: Standard TCP handshake followed by initial SMTP conversation. No errors.
Packet #12 Recipient MTA: TCP sequence 231. Ack 91.
Packet #13 FooMTA: TCP sequence 91. Ack 305.
Packet #14 FooMTA: TCP sequence 1115. Ack 305.
Packet #15 Recipient MTA: TCP sequence 305. Ack 2495.
Packet #16 FooMTA: TCP sequence 2495. Ack 305.
Packet #17 FooMTA: TCP sequence 5255. Ack 305.
Packet #18: Recipient MTA: TCP sequence 305. Ack 5255.
Packet #19: FooMTA: TCP sequence 6635. Ack 305.
Packet #20: FooMTA: TCP sequence 8015. Ack 305.
Packet #21: Recipient MTA: TCP Sequence 305. Ack 8015.
Packet #22: FooMTA: TCP Sequence 10775. Ack 305.
Packet #23: FooMTA: TCP Sequence 13535. Ack 305.
Packet #24: Recipient MTA: TCP sequence 305. Ack 10775
Packet #25: FooMTA: TCP Sequence 14915. Ack 305
情况一直如此,我的服务器仍然认为它没有收到序列 305……作为回应,远程端最终重新传输其先前的数据,认为它从未到达。最终,差距变得如此之大,以至于没有新数据发送,远程 MTA 不断重新传输旧内容。这导致了指数退避,最终远程端放弃了。
对我来说奇怪的是,我看到“丢失的” TCP 序列(在本例中为 305)返回到我的服务器(通过直接从 fooMTA 收集的数据包捕获)所以我不明白为什么我的服务器一直要求它。
这可能与防火墙有关吗?故障排除的下一步是什么?
答案1
尝试一下:在你的/etc/sysctl.conf在底部添加以下几行:
net.ipv4.tcp_rmem = 4096 87380 174760
net.ipv4.tcp_wmem = 4096 16384 131072
net.ipv4.tcp_window_scaling = 0
然后以root身份执行sysctl -p
如果此方法有效,则可以绕过问题。但不能解决问题。造成这种情况的原因可能多种多样,从路由器无法正确处理 TCP 窗口缩放,到交换机也存在此问题,甚至是电缆故障。在某些情况下,我发现网络接口设备驱动程序和上述所有情况的组合很奇怪。