net.ipv4.tcp_fin_timeout真实意义
官网解释:https://www.kernel.org/doc/html/latest/networking/ip-sysctl.html
百度的坑:
最初百度查到关于这个参数的结果,基本上都是这种解释:该参数控制tcp四次挥手过程中,主动请求断开连接的一方处于TIME_WAIT状态的时间,后面实践中发现,并非如此。
以下为四次挥手状态图:
经过实际测试,并查阅官方资料,发现该参数真实作用为:控制主动请求关闭tcp连接的一方,处于FIN-WAIT2状态的时间
手动配置Linux系统 net.ipv4.tcp_fin_timeout = 180,然后用telnet测试:
修改net.ipv4.tcp_fin_timeout = 60,测试结果:
看起来两者是相等的,但是,当修改值为其他某些值,结果并不完全相等,具体如何影响,任然不确定。
修改net.ipv4.tcp_fin_timeout = 10,每次会在23秒左右结束fin2状态,测试结果:
实际应用:
如果观察到服务器有大量处于FIN_WAIT2状态的连接,可以将net.ipv4.tcp_fin_timeout参数值调小,以便加快系统关闭处于FIN_WAIT2状态的TCP连接。
填坑:内核中关于改参数最终取值部分代码如下:
static inline int tcp_fin_time(const struct sock *sk)
{
int fin_timeout = tcp_sk(sk)->linger2 ? : sysctl_tcp_fin_timeout;
const int rto = inet_csk(sk)->icsk_rto;
if (fin_timeout < (rto << 2) - (rto >> 1))
fin_timeout = (rto << 2) - (rto >> 1);
return fin_timeout;
}
总的来说,这段代码的目的是确保fin_timeout的值不会太小,至少应该是rto的某个特定倍数(大约3.5倍,但实际上是3倍加上rto的一半,取决于rto的奇偶性)。也就是说如果sysctl里面配置参数过低,内核会根据当前rto(超时重传时间)动态调整,这样的调整可能是基于某些网络协议或应用的需求,以确保在特定情况下有足够的时间来处理某些事件或超时。
关于rto
rto(Retransmission TimeOut,重传超时时间)是tcp一个关键参数,用于控制当TCP连接中的数据包未能得到对方确认时,多久之后发送方应该重传这个数据包,这个值在TCP连接的整个生命周期中可能会根据网络条件动态调整,例如通过TCP的RTT(Round-Trip Time,往返时间)估计算法。在TCP/IP协议栈的实现中,管理重传超时是确保数据传输可靠性和效率的关键部分。当TCP数据包未能及时得到对方确认时,TCP会根据RTO的值来决定何时重传该数据包。如果RTO设置得太短,可能会导致不必要的重传,增加网络负担;如果设置得太长,则可能导致数据传输延迟。因此,TCP使用一系列算法(如指数退避算法)来动态调整RTO的值,以适应不断变化的网络条件。