Linux 服务器重新发送 SYN ACK

Linux 服务器重新发送 SYN ACK

我正在排除两个 Linux 机器之间的连接超时问题,似乎服务器堆栈上的 ACK 到 SYN-ACK 丢失了。

tcpdump 在服务器端完成。

客户端收到 syn-ack,发送 ACK 和数据包,并重新发送数据 4 次。服务器在发送 syn-ack 4 秒后重新发送 syn-ack,表明来自客户端的 ACK 在服务器堆栈上丢失。客户端以 ACK 进行响应。

然后大约 3 秒后客户端重新发送数据,并收到服务器的 ACK。客户端在 10 秒时发送 FIN,因为客户端应用程序设置了 10 秒的超时时间。

所以问题是:tcpdump 显示 SYN-ACK 的 ACK 已到达服务器。在哪种情况下服务器可以重新发送 SYN-ACK?是服务器端的内核问题还是应用程序问题?如何进一步调试?

感谢你的帮助。

20:31:01.159098 IP 客户端.cport > 服务器.sport:S 2848162415:2848162415(0)win 5840
20:31:01.159103 IP 服务器.sport > 客户端.cport:S 901143055:901143055(0)ack 2848162416 win 5792
20:31:01.159192 IP 客户端.cport > 服务器.sport:.ack 1 win 46
20:31:01.159276 IP 客户端.cport > 服务器.sport:P 1:426(425)ack 1 win 46
20:31:01.380395 IP 客户端.cport > 服务器.sport:P 1:426(425)ack 1 win 46
20:31:01.824367 IP 客户端.cport > 服务器.sport:P 1:426(425)ack 1 win 46
20:31:02.712362 IP 客户端.cport > 服务器.sport:P 1:426(425)ack 1 win 46
20:31:04.488358 IP 客户端.cport > 服务器.sport:P 1:426(425)ack 1 win 46
20:31:05.159038 IP 服务器.sport > 客户端.cport:S 901143055:901143055(0)ack 2848162416 win 5792
20:31:05.159157 IP 客户端.cport > 服务器.sport:.ack 1 win 46
20:31:08.040317 IP 客户端.cport > 服务器.sport:P 1:426(425)ack 1 win 46
20:31:08.040326 IP 服务器.sport > 客户端.cport:.ack 426 win 27
20:31:11.159618 IP 客户端.cport > 服务器.sport:F 426:426(0)ack 1 win 46
20:31:11.199139 IP 服务器.sport > 客户端.cport:.ack 427 win 27
20:31:14.724604 IP 服务器.sport > 客户端.cport:. 1:1449(1448)ack 427 win 27
20:31:14.724612 IP 服务器.sport > 客户端.cport:P 1449:1756(307)ack 427 win 27
20:31:14.724776 IP 客户端.cport > 服务器.sport:R 2848162842:2848162842(0)win 0
20:31:14.724779 IP 客户端.cport > 服务器.sport:R 2848162842:2848162842(0)win 0

编辑:存在大量溢出。应用程序的 listen() 积压量较低是否会导致出现此问题?

$ netstat -s | grep -i 列表
    210473 次套接字监听队列溢出
    210473 忽略 LISTEN 套接字的 SYN

编辑2:这是我在这里的第一篇帖子,所以请继续关注我。:)

客户端和服务器内核:2.6.18-92.el5

服务器应用程序:仅监听运动。它处理客户端请求并返回响应。使用 strace 我发现 listen() 积压是 5。

有 8 个客户端系统,每个系统运行一个客户端应用程序实例。客户端应用程序向服务器端口发送请求,从服务器获取响应。客户端成功执行 connect() 后会设置一个 10 秒的计时器。每个客户端实例可以发送多个连接请求,每个请求都在自己的客户端端口上。

8 个客户端可能会出现大量并发请求。

编辑3:tcpdump看起来与http://forum.openvz.org/index.php?t=msg&goto=25678,但没有根本原因/解决方案。

答案1

我问自己为什么普通客户会这样做:

  1. 将之前公布的数据窗口 5840 缩小到 46
  2. 重新发送相同数据段连续 5 次(其中 3 次在 1 秒内发生!)

此外,如果您需要社区的帮助,您最好认为我们很久以前就失去了心灵感应能力,因此我们甚至不知道这其中涉及到什么软件(从 Linux 内核版本开始)以及它应该做什么和如何工作。

答案2

您的 backlog 太小,无法接受所有请求。backlog 是您的 accept 队列的大小,当 accept 队列已满时,客户端的 ACK 将被忽略或根据 net.ipv4.tcp_abort_on_overflow 中止连接。因此,请增加您的 backlog。

相关内容