可承遇到,不知什么原因,一个夜晚,机房中,大片的远程调用连接断开。
第二天早上,用户访问高峰,大部分服务器都在获取连接,造成大片网络阻塞。
服务崩溃,惨不忍睹的景象。
本文将从长连接和短连接的概念切入,再到长连接与短连接的区别,以及应用场景,引出心跳机制和断线重连,给出代码实现。
从原理到实践杜绝此类现象。
短连接
概念
client与server通过三次握手建立连接,client发送请求消息,server返回响应,一次连接就完成了。
这时候双方任意都可以发起close操作,不过一般都是client先发起close操作。上述可知,短连接一般只会在 client/server间传递一次请求操作。
短连接的优缺点
管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。
使用场景
通常浏览器访问服务器的时候就是短连接。
对于服务端来说,长连接会耗费服务端的资源,而且用户用浏览器访问服务端相对而言不是很频繁的
如果有几十万,上百万的连接,服务端的压力会非常大,甚至会崩溃。
所以对于并发量大,请求频率低的,建议使用短连接。
长连接什么是长连接
client向server发起连接,server接受client连接,双方建立连接。
Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。
长连接的生命周期
正常情况下,一条TCP长连接建立后,只要双不提出关闭请求并且不出现异常情况,这条连接是一直存在的.
操作系统不会自动去关闭它,甚至经过物理网络拓扑的改变之后仍然可以使用。
所以一条连接保持几天、几个月、几年或者更长时间都有可能,只要不出现异常情况或由用户(应用层)主动关闭。
客户端和服务单可一直使用该连接进行数据通信。
长连接的优点
长连接可以省去较多的TCP建立和关闭的操作,减少网络阻塞的影响,
当发生错误时,可以在不关闭连接的情况下进行提示,
减少CPU及内存的使用,因为不需要经常的建立及关闭连接。
长连接的缺点
连接数过多时,影响服务端的性能和并发数量。
使用场景
数据库的连接就是采用TCP长连接.
RPC,远程服务调用,在服务器,一个服务进程频繁调用另一个服务进程,可使用长连接,减少连接花费的时间。
总结
1.对于长连接和短连接的使用是需要根据应用场景来判断的
2.长连接并不是万能的,也是需要维护的,
长连接的实现 心跳机制
应用层协议大多都有HeartBeat机制,通常是客户端每隔一小段时间向服务器发送一个数据包,通知服务器自己仍然在线。
并传输一些可能必要的数据。使用心跳包的典型协议是IM,比如QQ/MSN/飞信等协议。
在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。
系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。
而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。
为什么需要心跳机制?因为网络的不可靠性, 有可能在 TCP 保持长连接的过程中, 由于某些突发情况, 例如网线被拔出, 突然掉电等,
会造成服务器和客户端的连接中断. 在这些突发情况下, 如果恰好服务器和客户端之间没有交互的话, 那么它们是不能在短时间内发现对方已经掉线的.
心跳机制即可解决此类问题。
TCP协议的KeepAlive机制默认KeepAlive状态是不打开的。
需要将setsockopt将SOL_SOCKET.SO_KEEPALIVE设置为1才是打开KeepAlive状态,
并且可以设置三个参数:
tcp_keepalive_time ,tcp_keepalive_probes , tcp_keepalive_intvl,
分别表示:连接闲置多久开始发keepalive的ack包、发几个ack包不回复才当对方已断线、两个ack包之间的间隔。
很多网络设备,尤其是NAT路由器,由于其硬件的限制(例如内存、CPU处理能力),无法保持其上的所有连接,因此在必要的时候,会在连接池中选择一些不活跃的连接踢掉。
典型做法是LRU,把最久没有数据的连接给T掉。