tcp探活包tcp_keepalive
程序员文章站
2024-03-22 22:22:34
...
1 介绍
Tcp是面向连接的,一般情况下,两端是可以正常的通过发送接收数据得知是否存活;而当两端都没有数据怎么判断是否正常的呢。
系统默认keepalive是关闭的;可开启keepalive检查判断是否崩溃
2 属性参数
tcp_keepalive_time:两端多久没有数据交换,则开启发送keepalive探活包
tcp_keepalive_probes:发送多少次探活包
tcp_keepalive_intvi:探活包发送间隔
3 如何使用
可以在linux系统中使用,也可以在应用程序中通过代码使用。
3.1 系统级别
/etc/sysctl.conf文件中:
添加参数:
net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes=9
生效:sysctl -P
3.2 应用程序级别
单个连接可以在代码中使用,可使用三个属性设置: TCP_KEEPCNT/TCP_KEEPIDLE/TCP_KEEP_INTL
开启So_keepalive
开启接口:setsockopt():
redis源码开启:
// 开启tcp-keepaliveint val = 1;
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1)
{
anetSetError(err, "setsockopt SO_KEEPALIVE: %s", strerror(errno));
return ANET_ERR;
}
// 设置val = interval;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0)
{
anetSetError(err, "setsockopt TCP_KEEPIDLE: %s\n", strerror(errno));
return ANET_ERR;
}
/* Send next probes after the specified interval. Note that we set the * delay as interval / 3, as we send three probes before detecting * an error (see the next setsockopt call). */
val = interval/3;
if (val == 0) val = 1;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { anetSetError(err, "setsockopt TCP_KEEPINTVL: %s\n", strerror(errno));
return ANET_ERR;
}
/* Consider the socket in error state after three we send three ACK * probes without getting a reply. */
val = 3;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
anetSetError(err, "setsockopt TCP_KEEPCNT: %s\n", strerror(errno));
return ANET_ERR;
}
4 应用场景
为什么应⽤层需要开启⼼跳检测? :因为传输层探活检测,⽆法判断进程阻塞或者死锁的情况;
⼼跳检测: 每隔10秒发送⼀次⼼跳包 3次没有收到 close
- 数据库间,主从复制,使⽤⼼跳检测;
- 客户端与服务器,使⽤⼼跳检测;
- 客户端->反向代理->上游服务器;反向代理与上游服务器使⽤探活检测;
- 服务端->数据库,使⽤探活检测;对于数据库⽽⾔,服务端是否阻塞跟它⽆关;