服务端为什么需要心跳(保活)机制

如果没有特意的设置某些选项或者实现应用层心跳包,TCP空闲的时候是不会发送任何数据包。也就是说,当一个TCP的socket,客户端与服务端谁也不发送数据,会一直保持着连接。这其中如果有一方异常掉线(例如死机、路由被破坏、防火墙切断连接等),另一端如果没有发送数据,永远也不可能知道。这对于一些服务型的程序来说,是灾难性的后果,将会导致服务端socket资源耗尽。

  所以为了保证连接的有效性、及时有效地检测到一方的非正常断开,保证连接的资源被有效的利用,我们就会需要一种保活的机制,通常改机制两种处理方式:1、利用TCP协议层实现的Keepalive;2、自己在应用层实现心跳包。


  两种方式的对比如下:

  1、TCP协议自带的保活功能, 使用起来简单, 减少了应用层代码的复杂度. 更节省流量, 因为一般来说应用层的数据传输到协议层时都会被加上额外的包头包尾. 由TCP协议提供的检活, 其发的ACK包比应用层的心跳包耗费更少的流量。

  2、应用层心跳包相对与Keepalive更灵活,因为协议层的心跳只能提供最纯粹的检活功能, 但是应用层自己可以随意控制,甚至加入一些额外逻辑。

  3、应用层心跳包相对与Keepalive更灵活,应用层心跳包不依赖于协议,如若有一天不用TCP要改为UDP了,只需做少量改动甚至不用改动即可实现转换。


  网络上有说:存活(keepalive)并不是TCP规范的一部分。在Host Requirements RFC罗列有不使用它的三个理由:(1)在短暂的故障期间,它们可能引起一个良好连接(good connection)被释放(dropped),(2)它们消费了不必要的宽带,(3)在以数据包计费的互联网上它们(额外)花费金钱。

  实际上,自己实现心跳包也会面临同样的问题,而第一点,在我测试过程中,只要设置参数合理短时间内并不会引起连接主动断开

参考链接:

http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/#preventingdisconnection

http://www.felix021.com/blog/read.php?2076


猜你喜欢

转载自blog.csdn.net/yinni11/article/details/80062578