短连接的使用有很大的瓶颈,所以才会有长连接的使用空间,但是长连接也会因为某些原因断开。
短连接
早期HTTP1.0的协议都是建立在TCP协议基础上,其特点就是传输完数据后,立马就释放掉该TCP链接,所以就有了形象的短连接这个称号。
下图形象的展示出了在一个事务的处理过程中,各个阶段的处理时长:
可以看到,与建立TCP连接,以及传输请求和响应报文的时间相比,事务处理时间可能是很短的。
- 短连接的性能瓶颈主要集中在如下几个方面:
- TCP连接的握手时延
在发送数据之前,TCP要传送两个分组来建立连接(现代的TCP栈都允许客户端在确认分组中发送数据),此时,SYN/SYN+ACK握手会产生一个可测量的时延
- 延迟确认
每个TCP段都有一个序列号和数据完整性校验和。每个段的接收者收到完好的段时,都会向发送者回送小的确认分组。如果发送者没有在指定的窗口时间内收到确认信息,发送者就认为分组已被破坏或损毁,并重发数据。
由于确认报文很小,所以TCP允许在发往相同方向的输出数据分组中对其进行“捎带”。TCP将返回的确认信息与输出的数据分组结合在一起,可以更有效地利用网络。为了增加确认报文找到同向传输数据分组的可能性,很多TCP栈都实现了一种“延迟确认”算法。延迟确认算法会在一个特定的窗口时间(通常是100~200毫秒)内将输出确认存放在缓冲区中,以寻找能够捎带它的输出数据分组。如果在那个时间段内没有输出数据分组,就将确认信息放在单独的分组中传送。
- TCP慢启动
TCP连接会随着时间进行自我“调谐”,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度,这种调谐被称为TCP慢启动,用于防止因特网的突然过载和拥塞。
长连接保活,Keep-Alive与心跳保活技术
心跳保活
App实现长连接保活的方式通常是采用应用层心跳,通过心跳包的超时和其他条件(网络切换)来执行重连操作。心跳一般是指某端(绝大多数情况下是客户端)每隔一定时间向对端发送自定义指令,以判断双方是否存活,因其按照一定间隔发送,类似于心跳,故被称为心跳指令。
Keep-Alive能否实现保活
HTTP中的Keep-Alive
实现HTTP/1.0 keep-alive连接的客户端可以通过包含Connection:Keep-Alive首部请求将一条连接保持在打开状态,如果服务器愿意为下一条请求将连接保持在打开状态,就在响应中包含相同的首部。如果响应中没有Connection: Keep-Alive首部,客户端就认为服务器不支持keep-alive,会在发回响应报文之后关闭连接。HTTP/1.1以后Keep-Alive是默认打开的。
TCP中的Keep-Alive
TCP协议的实现中,提供了KeepAlive报文,用来探测连接的对端是否存活。在应用交互的过程中,可能存在以下几种情况:客户端或服务器意外断电,死机,崩溃,重启;
中间网络已经中断,而客户端与服务器并不知道;
- TCP保活报文交互过程如下:
虽然TCP提供了KeepAlive机制,但是并不能替代应用层心跳保活
1 | 1.HTTP协议的Keep-Alive意图在于TCP连接复用,同一个连接上串行方式传递请求-响应数据; |
影响心跳频率的关键因素
心跳过于频繁会带来耗电和耗流量的弊病,心跳频率过低则会影响连接检测的实时性。业内关于心跳时间的设置和优化,主要基于如下几个因素:
- NAT超时–大部分移动无线网络运营商在链路一段时间没有数据通讯时,会淘汰 NAT表中的对应项,造成链路中断;
- DHCP租期–DHCP租期到了需要主动续约,否则会继续使用过期IP导致长连接偶然的断连;
- 网络状态变化–手机网络和WIFI网络切换、网络断开和连上等情况有网络状态的变化,也会使长连接变为无效连接;