服务器发送 FIN、ACK 的时间太长
Server takes too long to send FIN, ACK
我有一个移动应用程序(捕获的是 186.18.33.118)从 php api (200.80.41.246) 的一些简单的 http 服务器请求数据。
当我从我的应用程序发送请求时,有一分钟无法从发送请求的同一个局域网访问 Web 服务器。
服务器是 Centos 7 apache 和所有更新。
我使用 tcpdump 分析了服务器和我的应用程序之间的数据包(下面显示了当我从应用程序请求到服务器以及从我的浏览器到服务器以使用 wireshark 打开之后的捕获)。
我能看到的奇怪的是服务器发送FIN数据包的时间太长,ACK
有什么问题吗?
EDIT/ADD
(我如何进行捕获的步骤)
我在 phone 中打开了该应用程序(该应用程序咨询安装在服务器 200.80.41.246 上的 wordpress)
几秒钟后,我尝试从浏览器(从连接到 cellphone 的同一个局域网)进入 wordpress
服务器给我消息说:错误超时(接近数据包45)
所以我尝试了很多次,大约一分钟后连接正常(靠近数据包110)
编辑 2
我比较了从浏览器和应用程序到 api 的查询,因为当我从浏览器发出请求时不会带来问题,我发现的区别是浏览器发送应用程序不发送的 RST 数据包。
下面我留个图,上面是浏览器查询,下面是app查询
有什么建议吗?
如果您能分享 tcpdump 将会很有帮助。通常 FIN 数据包会在某个超时值后发送,该超时值取决于 OS.
On Linux I 默认值为 60 秒。
看这里:TCP parameters, Linux kernel
编辑:
我查看了截图,发现了一些事情:
当服务器根本不使用 [SYN,ACK] 数据包响应 SYN 请求时,就会发生 TCP 重传。它尝试打开许多与服务器的会话,但服务器没有应答(~20 个会话)。 TCP 重传是 TCP 协议的一部分,它会在 3、6、12、24 等之后(取决于 TCP 堆栈实现)在未收到应答时发送重传,因此这是正常行为。
下一次服务器应答是在 ~48 秒后(从第一个没有应答的 SYN 开始)。我的猜测是服务器不会关闭会话并且在那段时间不接受其他会话。
这里您需要了解两件事:1. 连接关闭的 TCP 状态机。 2. 与连接关闭相关的 TCP 定时器。
总共有 7 个 TCP 计时器,其中“最大段生存期” 和 "retransmission" 计时器将在连接关闭的上下文中发挥作用。
现在关于 TCP 状态:客户端可以发起连接关闭,或者服务器也可以这样做。
"The server sends the client a packet with a "FIN”位设置,此时服务器处于FIN_WAIT_1状态,客户端收到FIN包进入CLOSE_WAIT状态,发送确认数据包返回服务器。当服务器收到该数据包时,它进入 FIN_WAIT_2 状态。从服务器的角度来看,连接现在已关闭,服务器无法再发送任何数据。但是,在 TCP 下协议,客户端还需要通过发送 FIN 数据包来关闭,服务器 TCP 实现应确认该数据包。服务器应在最大段生命周期 (MSL) 定义的一段时间后关闭。"
在任何时候,如果发件人没有收到确认信息,就会触发重传。
你应该根据你的具体情况寻找:
1 是 MSL 在您提到的延迟中扮演的角色。
2 是否有重传?是否存在虚假重传?
在分析 Linux 中的连接配置时,我发现了两个允许重用以前关闭的连接的参数,这些参数已启用。当我想从另一台具有相同 public IP 的设备访问时,在打开的连接发生冲突并且会有新的连接时,禁用现在可以正常工作。
参数为:
网.ipv4.tcp_tw_recycle
网.ipv4.tcp_tw_reuse
他们是 1(启用)
禁用执行命令
Sysctl net.ipv4.tcp_tw_recycle = 0
Sysctl net.ipv4.tcp_tw_reuse = 0
我有一个移动应用程序(捕获的是 186.18.33.118)从 php api (200.80.41.246) 的一些简单的 http 服务器请求数据。
当我从我的应用程序发送请求时,有一分钟无法从发送请求的同一个局域网访问 Web 服务器。
服务器是 Centos 7 apache 和所有更新。
我使用 tcpdump 分析了服务器和我的应用程序之间的数据包(下面显示了当我从应用程序请求到服务器以及从我的浏览器到服务器以使用 wireshark 打开之后的捕获)。
我能看到的奇怪的是服务器发送FIN数据包的时间太长,ACK
有什么问题吗?
EDIT/ADD
(我如何进行捕获的步骤)
我在 phone 中打开了该应用程序(该应用程序咨询安装在服务器 200.80.41.246 上的 wordpress)
几秒钟后,我尝试从浏览器(从连接到 cellphone 的同一个局域网)进入 wordpress
服务器给我消息说:错误超时(接近数据包45)
所以我尝试了很多次,大约一分钟后连接正常(靠近数据包110)
编辑 2
我比较了从浏览器和应用程序到 api 的查询,因为当我从浏览器发出请求时不会带来问题,我发现的区别是浏览器发送应用程序不发送的 RST 数据包。 下面我留个图,上面是浏览器查询,下面是app查询
有什么建议吗?
如果您能分享 tcpdump 将会很有帮助。通常 FIN 数据包会在某个超时值后发送,该超时值取决于 OS.
On Linux I 默认值为 60 秒。 看这里:TCP parameters, Linux kernel
编辑:
我查看了截图,发现了一些事情:
当服务器根本不使用 [SYN,ACK] 数据包响应 SYN 请求时,就会发生 TCP 重传。它尝试打开许多与服务器的会话,但服务器没有应答(~20 个会话)。 TCP 重传是 TCP 协议的一部分,它会在 3、6、12、24 等之后(取决于 TCP 堆栈实现)在未收到应答时发送重传,因此这是正常行为。
下一次服务器应答是在 ~48 秒后(从第一个没有应答的 SYN 开始)。我的猜测是服务器不会关闭会话并且在那段时间不接受其他会话。
这里您需要了解两件事:1. 连接关闭的 TCP 状态机。 2. 与连接关闭相关的 TCP 定时器。
总共有 7 个 TCP 计时器,其中“最大段生存期” 和 "retransmission" 计时器将在连接关闭的上下文中发挥作用。
现在关于 TCP 状态:客户端可以发起连接关闭,或者服务器也可以这样做。
"The server sends the client a packet with a "FIN”位设置,此时服务器处于FIN_WAIT_1状态,客户端收到FIN包进入CLOSE_WAIT状态,发送确认数据包返回服务器。当服务器收到该数据包时,它进入 FIN_WAIT_2 状态。从服务器的角度来看,连接现在已关闭,服务器无法再发送任何数据。但是,在 TCP 下协议,客户端还需要通过发送 FIN 数据包来关闭,服务器 TCP 实现应确认该数据包。服务器应在最大段生命周期 (MSL) 定义的一段时间后关闭。"
在任何时候,如果发件人没有收到确认信息,就会触发重传。
你应该根据你的具体情况寻找:
1 是 MSL 在您提到的延迟中扮演的角色。 2 是否有重传?是否存在虚假重传?
在分析 Linux 中的连接配置时,我发现了两个允许重用以前关闭的连接的参数,这些参数已启用。当我想从另一台具有相同 public IP 的设备访问时,在打开的连接发生冲突并且会有新的连接时,禁用现在可以正常工作。
参数为:
网.ipv4.tcp_tw_recycle
网.ipv4.tcp_tw_reuse
他们是 1(启用)
禁用执行命令
Sysctl net.ipv4.tcp_tw_recycle = 0
Sysctl net.ipv4.tcp_tw_reuse = 0