TCP Keepalive HOWTO
(原文网址:http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html)
3、linux下 TCP keepalive 套接字选项用法
linux系统中内置了keepalive选项的支持,在使用它之前除内核中支持 TCP/IP 网络模块外,还需要支持procfs或者sysctl。在系统运行过程中可通过proc或sysctl修改keepalive相关的内核参数。
使用keepalive选项的程序中需配置以下三个变量
tcp_keepalive_time
最后一个数据包被发送(只包含ACK的包不是数据包)到发送第一个keepalive心跳包的时间间隔,发送第一次心跳包后该连接就激活了keepalive心跳机制。在下一个数据包被发送/接收之前该变量不会被用到。
tcp_keepalive_intvl
keepalive心跳包发送的时间间隔。
tcp_keepalive_probes
在连接结束或者收到数据包前心跳包发送的次数。
注意:即使kernel中配置支持keepalive机制,linux默认并没开启此功能。应用程序必须使用setsockopt接口使能keepalive。使用keepalive心跳机制不需要编写很多代码,阅读这篇文档中后续部分你能很容易的在你的程序中增加keepalive机制。
3.1. 配置内核
有两种使用用户态命令的方法可以配置内核中的keepalive选项
procfs接口与sysctl接口
我们主要讨论如何能过procfs接口来配置,因为procfs方式最常用,也很容易理解。sysctl接口方式特指使用sysctl(2)系统调用而不是sysctl(8)工具命令。
3.1.1 procfs 接口
procfs接口需要内核中配置支持sysctl及profs,并且将procfs挂接在文件系统中(通常挂接在/proc目录上),在/proc/sys/net/ipv4/目录下使用cat命令能够读取各参数的值:
# 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
前面两个参数值的单位是秒,后一个参数值纯粹是数字。这意味着在发送第一个心跳包之前keepalive程序需等待两小时(7200s),每隔75s重发一次,如果连接发送9次心跳包都没有收到ack响应包连接就被标识为断开。
直接修改这些值:向文件中写入值来修改这些参数。如配置主机上的连接在十分钟后还不活跃就发送心跳包,并且每分钟发送一次;由于我们的网络主干很不稳定且默认的心跳包发送次数太少,假如你也想要将此值设置为20。
下面我们来修改配置:
# echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
# echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
# echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes
为了确定设置成功,重新查看这些文件
注意:procfs只是用户态操作内核空间的一种接口并不是真实的文件,因此你不能对它们执行sort操作。
你能使用sysctl(8)工具访问procfs接口来读/写内核参数。
# sysctl \
> net.ipv4.tcp_keepalive_time \
> net.ipv4.tcp_keepalive_intvl \
> net.ipv4.tcp_keepalive_probes
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
注意:sysctl工具中参数名称与procfs路径名非常相似。使用带'-w'参数的sysctl(8)工具表示执行写操作。
# sysctl -w \
> net.ipv4.tcp_keepalive_time=600 \
> net.ipv4.tcp_keepalive_intvl=60 \
> net.ipv4.tcp_keepalive_probes=20
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 20
注意:sysctl(8)并没有使用sysctl(2)系统调用接口,而是直接通过procfs子树来进行读写。因此内核中需要配置支持procfs并将其挂接到文件系统中。 sysctl(8)工具仅仅是做同一件事的另一种方式而已。
3.1.2 sysctl 接口
sysctl(2) 系统调用是访问内核变量的另一种方式,当你的系统中不存在procfs时直接使用sysctl(2)系统调用跟内核通信非常方便。使用sysctl(2)跟内核通信是直接通过系统调用并没有使用procfs子树。目前并没有程序封闭sysctl系统调用(注意:sysctl(8)并没有使用系统调用)。
有关sysctrl(2)的更多信息请参考man页
3.2 配置修改重启生效
有多种方式在系统每次启动后自动加载配置。一、所有linux发行版都有一套由init进程调用的初始化脚本,常用的配置存放在/etc/rc.d或/etc/init.d目录中。任何时候你都能在任何一脚本文件中添加keepalive选项参数值,因为每次用到keepalive心跳机制时都会重新读它。因此当连接存在时改变tcp_keepalive_intvl变量值后内核会使用新值。
初始化命令可以放在已下三个地方:一、网络配置脚本所在的地方,二、rc.local脚本文件中,所有的linux发行版中都包括rc.local脚本文件,三、回顾一下前面讲到的sysctl工具,使用带'-p'参数的sysclt命令显示出/etc/sysctl.conf配置文件中的配置信息。将keepalive配置选项添加到/etc/sysctl.conf文件中使它们每次启动时被加载。有关/etc/sysctl.conf(5)文件的更新信息请参考man页。
(原文网址:http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html)