swoole server中 tcp链接keep-alive保活设置很简单
官方文档: TCP服务器心跳维持方案
官方文档: TCP-Keepalive死连接检测
$serv->set(array(
'heartbeat_check_interval' => 5,
'heartbeat_idle_time' => 10,
));
那么swoole中keep-alive的原理是什么呢,在 src/network/Port.c 中
原理很简单,就是利用linux系统的 socket 的 SO_KEEPALIVE 属性, 实现系统层面的连接心跳检测
int swPort_listen(swListenPort *ls)
{
int sock = ls->sock;
int option = 1;
//listen stream socket
if (listen(sock, ls->backlog) < 0)
{
swWarn("listen(%s:%d, %d) failed. Error: %s[%d]", ls->host, ls->port, ls->backlog, strerror(errno), errno);
return SW_ERR;
}
#ifdef TCP_DEFER_ACCEPT
if (ls->tcp_defer_accept)
{
if (setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, (const void*) &ls->tcp_defer_accept, sizeof(int)) < 0)
{
swSysError("setsockopt(TCP_DEFER_ACCEPT) failed.");
}
}
#endif
#ifdef TCP_FASTOPEN
if (ls->tcp_fastopen)
{
if (setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, (const void*) &ls->tcp_fastopen, sizeof(int)) < 0)
{
swSysError("setsockopt(TCP_FASTOPEN) failed.");
}
}
#endif
#ifdef SO_KEEPALIVE
if (ls->open_tcp_keepalive == 1)
{
//设置 tcp心跳检测
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *) &option, sizeof(option)) < 0)
{
swSysError("setsockopt(SO_KEEPALIVE) failed.");
}
#ifdef TCP_KEEPIDLE
setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (void*) &ls->tcp_keepidle, sizeof(int));
setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (void *) &ls->tcp_keepinterval, sizeof(int));
setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (void *) &ls->tcp_keepcount, sizeof(int));
#endif
}
#endif
ls->buffer_high_watermark = ls->socket_buffer_size * 0.8;
ls->buffer_low_watermark = 0;
return SW_OK;
}
网友评论