可以通过设置系统内的tcp keepalive来缩短极端情况的断线吗?

啊哒梨

当服务端不要求客户端必须回应心跳检测时,假如客户端遇到掉电等极端情况,这时服务端向客户端发送的心跳数据在TCP层面就会发送超时,遇到这种超时情况TCP会重试多次(次数及间隔依赖操作系统的配置),多次无果后会断开连接。这种极端情况从连接断开到服务端检测到可能要持续至少10分钟才触发onClose事件回调。

可以通过以下的设置来缩短超时情况下的断线吗?

$ vim /etc/sysctl.conf
    net.ipv4.tcp_keepalive_time = 200
    net.ipv4.tcp_keepalive_probes = 5
    net.ipv4.tcp_keepalive_intvl = 30
$ sysctl -p

以上设置以后似乎没有效果,使用 Gateway::getAllClientSessions() 依旧可以看到该连接,在设备断电第17分钟左右(有时候还要更久一点),该连接才下线。

求大大答疑解惑~

阅读 2049
1个回答

walkor

看了些资料有这样的说法,我没有做验证,你看下

正常情况下,连接的另一端主动调用colse关闭连接,tcp会通知,我们知道了该连接已经关闭。但是如果tcp连接的另一端突然掉线,或者重启断电,这个时候我们并不知道网络已经关闭。而此时,如果有发送数据失败,tcp会自动进行重传。重传包的优先级高于keepalive,那就意味着,我们的keepalive总是不能发送出去。 而此时,我们也并不知道该连接已经出错而中断。在较长时间的重传失败之后,我们才会知道。

另外net.ipv4.tcp_keepalive_time = 200 貌似太长了,200秒有些路由节点可能已经把连接路由清理了。
最好是60秒以内