TCP链接keepalive机制介绍

Posted Simple is Better.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP链接keepalive机制介绍相关的知识,希望对你有一定的参考价值。

什么是KeepAlive

KeepAlive可以简单理解为一种状态保持或重用机制,比如当一条连接建立后,我们不想它立刻被关闭,如果实现了KeepAlive机制,就可以通过它来实现连接的保持。
简单的说就是当你跟女朋友打电话但是没话讲,又不能挂的时候,每隔固定周期喊一声“喂你还在吗”的机制。

TCP为什么要做KeepAlive

image

  1. 我们都知道TCP的三次握手和四次挥手。当两端通过三次握手建立TCP连接后,就可以传输数据了,数据传输完毕,连接并不会自动关闭,而是一直保持。只有两端分别通过发送各自的 FIN 报文时,才会关闭自己侧的连接。
  2. 这个关闭机制看起来简单明了,但实际网络环境千变万化,衍生出了各种问题。假设因为实现缺陷、突然崩溃、恶意攻击或网络丢包等原因,一方一直没有发送 FIN 报文,则连接会一直保持并消耗着资源,为了防止这种情况,一般接收方都会主动中断一段时间没有数据传输的TCP连接,比如LVS会默认中断90秒内没有数据传输的TCP连接,F5会中断5分钟内没有数据传输的TCP连接
  3. 但有的时候我们的确不希望中断空闲的TCP连接,因为建立一次TCP连接需要经过一到两次的网络交互,且由于TCP的 slow start 机制,新的TCP连接开始数据传输速度是比较慢的,我们希望通过连接池模式,保持一部分空闲连接,当需要传输数据时,可以从连接池中直接拿一个空闲的TCP连接来全速使用,这样对性能有很大提升
  4. 为了支持这种情况,TCP实现了KeepAlive机制。KeepAlive机制并不是TCP规范的一部分,但无论Linux和Windows都实现实现了该机制。TCP实现里KeepAlive默认都是关闭的,且是每个连接单独设置的,而不是全局设置

Implementors MAY include "keep-alives" in their TCP implementations, although this practice is not universally accepted. If keep-alives are included, the application MUST be able to turn them on or off for each TCP connection, and they MUST default to off.

另外有一个特殊情况就是,当某应用进程关闭后,如果还有该进程相关的TCP连接,一般来说操作系统会自动关闭这些连接

如何查看TCP的keepalive参数配置

Linux中KeepAlive相关的配置可以通过如下方式查看

cat /proc/sys/net/ipv4/tcp_keepalive_time
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
cat /proc/sys/net/ipv4/tcp_keepalive_probes

在Linux中我们可以通过修改内核参数 /etc/sysctl.conf 的全局配置:

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9

添加上面的配置后输入 sysctl -p 使其生效,你可以使用 sysctl -a | grep keepalive 命令来查看当前的默认配置

如果应用中已经设置SO_KEEPALIVE,程序不用重启,内核直接生效

如何监测TCP连接的keepalive状态

ss -aoen|grep ESTAB

观察结果中的timer,为程序中定义的keepalive定时器,持续执行可以看到时间缩小后再次计时。
image

以上是关于TCP链接keepalive机制介绍的主要内容,如果未能解决你的问题,请参考以下文章

不为人知的网络编程:彻底搞懂TCP协议层的KeepAlive保活机制

聊聊 TCP 中的 KeepAlive 机制

为什么要使用 TCP keepalive?C/C++代码实现TCP keepalive

TCP_KEEPALIVE机制简述

闲说HeartBeat心跳包和TCP协议的KeepAlive机制

不为人知的网络编程:彻底搞懂TCP协议层的KeepAlive保活机制