聊一聊nginx开启TCP Keep-Alives

2 篇文章 0 订阅

TCP标准

Keep-Alives并不是TCP协议规范的一部分,但在几乎所有的TCP/IP协议栈(不管是Linux还是Windows)中,都实现了Keep-Alives功能。
RFC1122中有如下描述:

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.
Keep-alive packets MUST only be sent when no data or acknowledgement packets have been received for the connection within an interval. This interval MUST be configurable and MUST default to no less than two hours. It is extremely important to remember that ACK segments that contain no data are not reliably transmitted by TCP.
Consequently, if a keep-alive mechanism is implemented it MUST NOT interpret failure to respond to any specific probe as a dead connection.
An implementation SHOULD send a keep-alive segment with no data; however, it MAY be configurable to send a keep-alive segment containing one garbage octet, for compatibility with erroneous TCP implementations.

大概说了这两点点:
如果实现了KeepAlive功能:

  1. KeepAlive默认情况下是关闭的,必须可以被应用程序开启和关闭;
  2. KeepAlive的空闲时长(即没有数据发送),默认值不能少于7200s(2小时);
  3. 空闲时长达到设置的阈值时,发送心跳探测包不能携带正常数据;

linux对TCP KeepAlive的支持

linux在实现TCP协议时,也是支持了KeepAlive功能的,并且按照【标准】里指导说明做了如下配置:

cat /proc/sys/net/ipv4/tcp_keepalive_time #默认值7200s
cat /proc/sys/net/ipv4/tcp_keepalive_intvl#默认值75s
cat /proc/sys/net/ipv4/tcp_keepalive_probes#默认值9次

这里三个配置理解如下:

我们看到这个tcp_keepalive_time的值默认为7200s,也就是2个小时,这个值代表TCP连接发送完最后一个ACK包后,如果TCP之间在tcp_keepalive_time(7200s,2h)后仍然没有任何数据来往,服务器给客户端发送一个探测包,如果对方有回应,说明这个连接还存活,否则继续每隔tcp_keepalive_intvl(默认为75s)给对方发送探测包,如果连续tcp_keepalive_probes(默认为9)次后,依然没有收到对端的回复,那么服务端就任务客户端已经死掉了,服务端就会关闭这个tcp连接并释放相应的资源。

在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 命令来查看当前的默认配置。

使用C的 socket库设置KeepAlive

#include <sys/socket.h>

//int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);

int keepalive = 1;
setsockopt(incomingsock,SOL_SOCKET,SO_KEEPALIVE,(void*)(&keepalive),(socklen_t)sizeof(keepalive));//开启keep-alives
                         
int keepalive_time = 30;
setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPIDLE,(void*)(&keepalive_time),(socklen_t)sizeof(keepalive_time));//设置tcp_keepalive_time

int keepalive_intvl = 20;
setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPINTVL,(void*)(&keepalive_intvl),(socklen_t)sizeof(keepalive_intvl));//设置tcp_keepalive_intvl

int keepalive_probes= 10;
setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPCNT,(void*)(&keepalive_probes),(socklen_t)sizeof(keepalive_probes));//设置tcp_keepalive_probes

设置SO_KEEPALIVE选项来开启KEEPALIVE,然后通过TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT设置keepalive的保活时间、间隔、次数等参数。

nginx 开启并配置KeepAlive

啰嗦这么多,才到正文,哎,差评。。。。。。。

nginx开启KeepAlive有两种方式:

  1. 使用listen指令下的so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt] 关键字,此选项自2011-12-12在nginx 1.1.11及更高版本中可用;
  2. 使用Nicolas Viennotnginx-tcp-keepalive模块提供了位置级别的tcp_keep *指令族。该模块应该可以在现代Linux和BSD系统上正常运行, Mac OS X支持仅限于tcp_keepalive.该模块最初是在nginx获得so_keepalive选项时发布的,不知此模块是否仍然与更新版本的nginx兼容,我没有尝试过,推荐第一种。

第一种的参数说明:so_keepalive=30m::10
表示开启了Keep-Alive,并将tcp_keepalive_time设置为30m,tcp_keepalive_intvl取系统默认值75s,tcp_keepalive_probes设置为10次

参考

1:是否可以配置Nginx发送TCP keepalive?
2:聊聊 TCP 长连接和心跳那些事
3:nginx官方文档
4:Nginx使用keepalive复用tcp连接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值