共计 3304 个字符,预计需要花费 9 分钟才能阅读完成。
一 基本原理
TCP 的 Keepalive 可以简单理解成为 keep tcp alive,用来检测 TCP sockets 的连接是否正常或是已经断开。
Keeplived 的原理很简单,当建立一个 TCP 连接时,发送端就会创建一些计时器,其中一些计时器就是处理 keeplaive 相关问题的。当 keepalive 的计时器计数到 0 时,发送端就会向对端发送一些不含数据的 keepalive 数据包并开启 ACK 标志。如果得到 keepalive 探测包的回复,就可以认为当前的 TCP 连接正常,不用担心用户层面的具体实现。事实上,TCP 允许处理数据流,而不是数据包,所以对于用户程序来说零字节的数据包没有危害。
开启 keepalive 会对防火墙或者路由器产生额外的流量。
keepalive 主要承担两个任务:
检测死掉的对端连接
keepalive 可以用于在对端死掉并发送通知之前检测到对端的连接状态。内核错误或者强制终止对端的应用程序进程都可能造成这种情况发生。还有一种情况使用 keepalive 来检测对端是否死掉是对端依然存活但是连接到对端之前的网络已经断开。
假想主机 A 和主机 B 之前一个简单的 TCP 连接:在 A 与 B 之间有一个简单的三次握手,A 发送 SYN 到 B,然后 B 发送 SYN+ACK 到 A,最后 A 发送 ACK 到 B。现在就建立起了一个稳定的 TCP 连接,等待某方通过这个通道传输数据。现在问题就来了:拔掉主机 B 的电源,主机 B 在没有任何通知主机 A 当前连接即将关闭的情况会立即关机。对于主机 A,正准备接收数据,但是不知道主机 B 已经关机。现在主机 B 开机,主机 A 和主机 B 又处于正常状态,主机 A 知道还有一个与主机 B 的活动连接,但是主机 B 不知道。当主机 A 尝试通过这个死掉的连接向主机 B 发送数据时,主机 B 会返回 RST,主机 A 就会主动关掉这个连接。
keepalived 可以在对端主机不可达的情况通知发送端,减少误报的风险。实际上,如果网络中的两个主机存在这种问题,keepalive 会在标记一个连接端口之前等待一段时间并重新尝试发送 keepalive 数据包
_____ _____
| | | |
| A | | B |
|_____| |_____|
^ ^
|—>—>—>————– SYN ————–>—>—>—|
|—<—<—<———— SYN/ACK ————<—<—<—|
|—>—>—>————– ACK ————–>—>—>—|
| |
| system crash —> X
|
| system restart —> ^
| |
|—>—>—>————– PSH ————–>—>—>—|
|—<—<—<————– RST ————–<—<—<—|
| |
2. 在网络断开的情况下阻止与对端的 TCP 连接断开。
_____ _____ _____
| | | | | |
| A | | NAT | | B |
|_____| |_____| |_____|
^ ^ ^
|—>—>—>—|———– SYN ————->—>—>—|
|—<—<—<—|——— SYN/ACK ———–<—<—<—|
|—>—>—>—|———– ACK ————->—>—>—|
| | |
| | <— connection deleted from table |
| | |
|—>- PSH ->—| <— invalid connection |
| | |
二 在 Linux 下使用 TCP 的 keepalive
tcp_keepalive_time
一个连接需要 TCP 开始发送 keepalive 探测数据包之前的空闲时间。以秒为单位
tcp_keepalive_probes
发送 TCP keepalive 探测数据包的最大数量,默认是 9. 如果发送 9 个 keepalive 探测包后对端仍然没有响应,就关掉这个连接
tcp_keepalive_intvl
发送两个 TCP keepalive 探测数据包的间隔时间,默认是 75 秒
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
$ cat /proc/sys/net/ipv4/tcp_keepalive_probes
9
$ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
可以通过 echo 临时修改
echo “300” > /proc/sys/net/ipv4/tcp_keepalive_time
也可以通过修改 /etc/sysctl.conf 永久生效
$ grep net.ipv4.tcp_keepalive_time /etc/sysctl.conf
net.ipv4.tcp_keepalive_time = 300
$ sysctl -p|grep net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_time = 300
参考资料:
http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/index.html
CentOS 6.3 下 Haproxy+Keepalived+Apache 配置笔记 http://www.linuxidc.com/Linux/2013-06/85598.htm
Haproxy + KeepAlived 实现 WEB 群集 on CentOS 6 http://www.linuxidc.com/Linux/2012-03/55672.htm
Keepalived+Haproxy 配置高可用负载均衡 http://www.linuxidc.com/Linux/2012-03/56748.htm
Haproxy+Keepalived 构建高可用负载均衡 http://www.linuxidc.com/Linux/2012-03/55880.htm
CentOS 7 上配置 LVS + Keepalived + ipvsadm http://www.linuxidc.com/Linux/2014-11/109237.htm
Keepalived 高可用集群搭建 http://www.linuxidc.com/Linux/2014-09/106965.htm
Keepalived 的详细介绍 :请点这里
Keepalived 的下载地址 :请点这里
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2015-03/115321.htm