长连接与keepalive

缘起:

有这么一些服务器软件(如: tokyotyrant、memcached),他们提供长连接的功能,简单说,server端基本不会主动关闭连接的;非长连接的时候也会存在这种问题,只是长连接时会表现的更明显一下。如果客户端抽风(或者一些恶意的目的),打开连接后,并不关闭而直接离开,这样,就会在server端残留大量的连接,最直接的表象就是: netstat -anpt 时很慢。

真实案例:

具体原因未明,来个命令:

sar -n SOCK :

我们发现在1:30 PM时,tcp连接数突然飙升到 40万, 没有做任何操作3:40 PM时,连接数就开始减少了。

 

原因:

连接2小时没有操作,探活机制发现对方已经消失,于是,关闭了连接; 看了一下tokyotyrant 和 memcached的源码,都做了KEEPALIVE 的设置:

只是都没有做平静时间的设置,于是就都参考系统的设置了。

 

教训:

1. 如果没有keepalive的机制,系统运行时间过长总会出现这样的问题的

 

学习:

关于keep-alive的一些参数设置,摘自: man tcp :

tcp_keepalive_intvl (integer; default: 75)
The number of seconds between TCP keep-alive probes.

如果探活时,对方没有反应则,间隔 tcp_keepalive_intvl 秒后重发探活数据包,避免因丢包产生的探活差错

tcp_keepalive_probes (integer; default: 9)
The maximum number of TCP keep-alive probes to send before giving up and killing the connection if no
response is obtained from the other end.

如果发送了 tcp_keepalive_probes 次探活数据包,对方都没有反应,则视为对方死掉,而不是探活1次失败就放弃

tcp_keepalive_time (integer; default: 7200)
The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes.
Keep-alives are only sent when the SO_KEEPALIVE socket option is enabled. The default value is 7200 sec-
onds (2 hours). An idle connection is terminated after approximately an additional 11 minutes (9 probes
an interval of 75 seconds apart) when keep-alive is enabled.

Note that underlying connection tracking mechanisms and application timeouts may be much shorter.

从连接平静开始,间隔 tcp_keepalive_time 秒开始探活,避免对方异常退出

编程实现:

使用setsockopt(…) 函数来实现:

参考资料: http://ez.analog.com/docs/DOC-1862

 

 

 

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据