netpoll icon indicating copy to clipboard operation
netpoll copied to clipboard

SetIdleTimeout调用SetKeepAlive的原因?

Open Leoyoungxh opened this issue 4 years ago • 13 comments
trafficstars

Connection接口中SetIdleTimeout的具体实现是调用了SetKeepAlive,我的理解是连接的空闲时间超过了Idle timeout后连接被关闭,但是KeepAlive应该是定期发送维持连接存活的报文,怎么能实现超过空闲时间后连接被关闭呢?

Leoyoungxh avatar Oct 18 '21 07:10 Leoyoungxh

是的,这个确实没有找到很好的实现,主要是代价较大,我们再评估一下,或考虑移除它。 现在可能要自定义实现,通过 context 或者 timer。

Hchenn avatar Oct 18 '21 08:10 Hchenn

确实,踢空闲连接和 keep alive 没什么关系,踢掉空闲连接需要类似于 timer 的东西来支持,可以参考 muduo 书的 7.10 使用时间轮来踢

WineChord avatar Nov 02 '21 02:11 WineChord

确实,踢空闲连接和 keep alive 没什么关系,踢掉空闲连接需要类似于 timer 的东西来支持,可以参考 muduo 书的 7.10 使用时间轮来踢

Do you have an example of this implementation we can use as a workaround in the meantime?

da-tai avatar Dec 19 '21 04:12 da-tai

确实,踢空闲连接和 keep alive 没什么关系,踢掉空闲连接需要类似于 timer 的东西来支持,可以参考 muduo 书的 7.10 使用时间轮来踢

Do you have an example of this implementation we can use as a workaround in the meantime?

You may refer to http://www.cs.columbia.edu/~nahum/w6998/papers/ton97-timing-wheels.pdf.

And Google something like heap-based timer, timing-wheel, etc.

WineChord avatar Dec 31 '21 07:12 WineChord

其实就是 SetReadDeadline,timing-wheel 不够精确、tick间隔越低越精确但是就可能empty loop更多,所以并不是很划算,定时器这种优先级队列场景还是 heap timer 更好些。有兴趣可用参考下我这的实现: https://github.com/lesismal/nbio/blob/master/conn_unix.go#L223

lesismal avatar May 01 '22 01:05 lesismal

cool

HeyJavaBean avatar Mar 27 '23 07:03 HeyJavaBean

其实就是 SetReadDeadline,timing-wheel 不够精确、tick间隔越低越精确但是就可能empty loop更多,所以并不是很划算,定时器这种优先级队列场景还是 heap timer 更好些。有兴趣可用参考下我这的实现: https://github.com/lesismal/nbio/blob/master/conn_unix.go#L223

评论区出人才

someview avatar Dec 25 '23 08:12 someview

其实就是 SetReadDeadline,timing-wheel 不够精确、tick间隔越低越精确但是就可能empty loop更多,所以并不是很划算,定时器这种优先级队列场景还是 heap timer 更好些。有兴趣可用参考下我这的实现: https://github.com/lesismal/nbio/blob/master/conn_unix.go#L223

评论区出人才

早期用的自实现的heap timer,但其实用在deadline这种超时后的回调只是close的fast callback场景,标准库timer也是足够了,所以把早期版本自实现的heap timer废弃了,现在用的是标准库timer,之前的链接已经失效了,新的: https://github.com/lesismal/nbio/blob/master/timer/timer.go#L46

lesismal avatar Dec 25 '23 08:12 lesismal

另外,tcp keepalive和应用层的keepalive是有区别的,之前gnet里有人问、也聊过这个: https://github.com/panjf2000/gnet/issues/332#issuecomment-1066725834

lesismal avatar Dec 25 '23 08:12 lesismal

连接少的场景其实都没有设置这个的必要,所以考虑的场景至少也是上万连接的场景。而上万连接对象时,维护 idle time 的代价可能会非常高。这也是为什么一直没实现的原因。

即便用go timer,上万的timer在go runtime中,且还需要不停modtimer(因为连接会有新读写),代价也是很大的。

joway avatar Jan 04 '24 06:01 joway

@joway 标准库heap timer代价没那么大的,一万个连接一点都不算大

lesismal avatar Jan 04 '24 07:01 lesismal