美文网首页
swoole源码-tcp链接keep-alive机制

swoole源码-tcp链接keep-alive机制

作者: cc180912 | 来源:发表于2018-12-10 19:39 被阅读8次

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 属性, 实现系统层面的连接心跳检测

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;
}

相关文章

网友评论

      本文标题:swoole源码-tcp链接keep-alive机制

      本文链接:https://www.haomeiwen.com/subject/knvdhqtx.html