TCP keepalive 概述(译)

什么是 TCP keepalive

TCP keepalive 概念很简单:当创建一个TCP链接时,会设置了一系列与该链接相关的定时器。其中有些定时器跟处理 keepalive 相关,在 keepalive 定时器倒计时变为零时,会给链接的另外一方发送一个 keepalive 探针包(probe packet),包内没有数据且设置了 ACK 标识。html

若是收到一个 keepalive 探针包的响应,说明链接是正常和有效的。TCP 能够处理只有协议头,但实际数据长度为零的数据包。这种机制是有用的,假如其余主机断开了链接,你能够及时注意到链接的断开。网络

若是 keepalive 探针没有响应,那么能够认为链接不是有效的,进而能够采起正确的操做。tcp

TCP keepalive 的应用场景

KeepAlive 是非侵入性的,大多数状况下开启 keepalive 不会有其余风险。须要注意的是,这样作会带来额外的网络开销,例如会影响到路由器和防火墙。.net

  • 检测实际断掉的链接
  • 维持客户端与 NAT 间的活跃网络包

检测实际断掉的链接

设想 A、B 两端建有 TCP 链接:最开始是三次握手,A 发送 SYN 报文段给 B,B 响应 SYN/ACK 给 A,最后 A 发送 ACK 给 B。如今两端处于 established 状态,都在等待对方发送数据。若是此时 B 电源被拔掉,在没有发送任何数据的通知 A 的状况下,B 已经断开了链接。A 已经作好了准备接收数据,但不知道 B 已经宕机。以后 B 恢复供电而且系统重启,A 觉得跟 B 的链接仍是正常的。此时 A 试图给 B 发送数据,B 会回复 RST 包,这样 A 才关闭这个链接。rest

Keepalive 机制可让 A 端避免出现上述的状况。实际上,若是链接双方有网络问题,keepalive 经过定时发送 keepalive 已经及时感知到链接断开。code

_____                                                     _____
   |     |                                                   |     |
   |  A  |                                                   |  B  |
   |_____|                                                   |_____|
      ^                                                         ^
      |--->--->--->-------------- SYN -------------->--->--->---|
      |---<---<---<------------ SYN/ACK ------------<---<---<---|
      |--->--->--->-------------- ACK -------------->--->--->---|
      |                                                         |
      |                                       system crash ---> X
      |
      |                                     system restart ---> ^
      |                                                         |
      |--->--->--->-------------- PSH -------------->--->--->---|
      |---<---<---<-------------- RST --------------<---<---<---|
      |                                                         |

维持客户端与 NAT 间的活跃网络包

keepalive 另外一个用途是阻止因网络链接不活跃(长时间没有数据包)而致使的链接断开。htm

不少网络设备,尤为是NAT路由器,因为其硬件的限制(例如内存、CPU处理能力),没法保持其上的全部链接,所以在必要的时候会在链接池中选择一些不活跃的链接踢掉。典型作法是LRU,把最久没有数据的链接给踢掉。经过使用 TCP KeepAlive 机制,可让链接每隔一小段时间就产生一些 ACK 包,以下降被踢掉的风险,固然,这样的代价是额外的网络和 CPU 负担。ip

_____           _____                                     _____
   |     |         |     |                                   |     |
   |  A  |         | NAT |                                   |  B  |
   |_____|         |_____|                                   |_____|
      ^               ^                                         ^
      |--->--->--->---|----------- SYN ------------->--->--->---|
      |---<---<---<---|--------- SYN/ACK -----------<---<---<---|
      |--->--->--->---|----------- ACK ------------->--->--->---|
      |               |                                         |
      |               | <--- connection deleted from table      |
      |               |                                         |
      |--->- PSH ->---| <--- invalid connection                 |
      |               |                                         |

Linux 系统中的 keepalive

Linux 中跟 keepalive 相关的三个参数:内存

  • tcp_keepalive_time
  • tcp_keepalive_intvl
  • tcp_keepalive_probes

tcp_keepalive_time
发送最后一个数据包(只包含 ACK 的包不认为是数据包)和发送第一个 probe 包之间间隔的时间路由

tcp_keepalive_intvl
发送两个 keepalive probe 包之间间隔多长

tcp_keepalive_probes
连续发几个 probe 包不回复才认为链接断了

默认值

# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200

# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75

# cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

HTTP Keep-Alive是什么?如何工做?
TCP-Keepalive

相关文章
相关标签/搜索