美文网首页
tcp keepalive

tcp keepalive

作者: 飞起一砣子 | 来源:发表于2017-11-23 00:12 被阅读37次

    起因

    今天排查的一个故障,和tcp keepalive有些相关,不过以前阅读UNP时太过随意,因此一直不太了解其机制,这个故障虽然也不是由 tcp keepalive引起的,不过正好也可以总结一下这方面的知识。

    tcp keepalive 是 what

    根据 linux-doc,tcp keepalive,顾名思义,keep tcp alive,是内核的一种检测tcp链接状态的机制。通俗的说,内核通过一系列的定时器,用来检测tcp链路的对端是否还在线,如果离线并达到一定的条件,内核就会认为链路失效,从而通知应用进行相应的处理

    爱与恨

    既然是这么一个好东西,那岂不是不要白不要?是的,tcp keepalive是无侵入式的,只需要在创建socket之后,用setsocketopt设置 SO_KEEPALIVE标志位即可享受内核级别的健康检查

    不过,任何招式都不能走遍天下,tcp keep alive虽然能够有效的解决断链的问题,不过如果有大量的tcp链路开启了keepalive,网络上将可能充斥着大量的心跳包,这是一个不小的负担,因此,具体问题具体分析,还是需要根据应用场景来选择是否开启这个选项。

    keepalive的几个参数

    在sysctl中,keepalive还有几个参数可以配置,分别是:

    tcp_keepalive_time
        the interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further 
    
    tcp_keepalive_intvl
        the interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime
    
    tcp_keepalive_probes
        the number of unacknowledged probes to send before considering the connection dead and notifying the application layer
    

    即,加入经过tcp_keepalive_time,链路上还没有数据流动,则进入tcp keepalive probe阶段,每隔tcp_keepalive_intvl秒,内核给对端发送一个keepalive probe包,如果连续发送了tcp_keepalive_probes个仍然没有回应,则认为链路已经失效,从而通知应用程序。

    PS:由于用于probe的包只是普通的ack包,因此tcp keepalive只需要本端支持即可,无需双方都有这个功能

    nginx中的 keepalive和 proxy_timeout

    nginx的stream模块中,listen指令可以配置一个 so_keepalive的参数,用于开启tcp keepalive,同时也能配置上述的三个参数,另外一个和keepalive机制类似的,则是proxy_timeout指令,这个指令在http和stream中都存在,意思是nginx和upstream之间,如果在proxy_timeout秒还没有数据交互,则nginx会关闭链接。

    本次遇到的故障,就是在nginx作为网关时,其后面的服务和客户端之间需要维持一个”长连接“,即双方很可能几个小时都不收发数据,但是nginx默认的proxy_timeout为10分钟。
    因此每隔十分钟,客户端发送的数据就会丢失一次,因为nginx关闭与后端的连接后,客户端下一次写会收到一个 RST包,只能重新三次握手建链后重新发送,当将proxy_timeout设置为一个足够大的数之后,问题就得到了解决

    相关文章

      网友评论

          本文标题:tcp keepalive

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