Keep alive和WebSocket区别

Posted by KANG's BLOG on Tuesday, March 15, 2022

1. keep alive和WebSocket协议介绍

Keep alive是HTTP 1.1协议提供的TCP保活机制,其通过在响应头中加入Connection:keep-alive来标识,允许在一次TCP连接中,完成多个HTTP请求。

换句话说,该协议主要解决的是每次HTTP请求都要进行三次握手的问题。

但是每个请求仍要单独发送header。

对比而言,WebSocket是HTML5出的协议(所以对浏览器版本有要求:IE10以上),跟HTTP协议没有关系,只是借用HTTP协议来完成握手,之后可以进行客户端和服务端的双工通信。

所以WebSocket的优点在于:

  • 减少了连接握手次数
  • 每次请求不需要发送header
  • 双向通信

缺点也是显而易见的,除了浏览器的兼容问题,错综复杂的网络环境也会对WebSocket造成影响,比如nginx对访问超时的判定。

2. WebSocket的心跳机制

每一次请求不是两点之间的访问交互,而是会跨越非常多的中间节点,而每一个中间节点都有可能有自己超时判定,这就带来非常多的不确定性。

所以WebSocket还提供了ping-pong机制,即前端定时发送心跳ping消息,后端收到后立马回复pong消息,告知前端连接正常。如果一段时间没有收到pong消息,就说明连接不正常,前端便会执行重连。

3. nginx对keep-alive的支持

nginx通过keepalive_timeout指令来设置keep-alive的超时时长,默认为60秒。即每一次请求发送完成后,如果60秒内没有请求发送,那么将关闭该TCP连接。

nginx还提供了每个TCP连接中最多发送请求数的配置:keepalive_requests,默认是100。针对并发较高的场景可以适当调高该配置提来提供更好的并发性能,减少TIME_WAIT状态的socket连接。

同时设置nginx支持长连接时,需要添加proxy_set_header_Connection "",即清空请求头,防止客户端传递短连接的请求头

4. socket的TIME_WAIT状态

TIME_WAIT是TCP连接断开时必定会出现的状态,是TCP协议实现的一部分。

TCP的TIME_WAIT状态也称为2MSL等待状态,2MSL即两倍的MSL(Maximum Segment Lifetime)。当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。

linux下查询TCP连接状态的命令:

netstat -ant|awk '/^tcp/ {++S[$NF]} END {for(a in S) print (a,S[a])}'

TCP连接状态含义:

  • CLOSED:无连接是活动的或正在进行
  • LISTEN:服务器在等待进入呼叫
  • SYN_RECV:一个连接请求已经到达,等待确认
  • SYN_SENT:应用已经开始,打开一个连接
  • ESTABLISHED:正常数据传输状态
  • FIN_WAIT1:应用说它已经完成
  • FIN_WAIT2:另一边已同意释放
  • ITMED_WAIT:等待所有分组死掉
  • CLOSING:两边同时尝试关闭
  • TIME_WAIT:另一边已初始化一个释放
  • LAST_ACK:等待所有分组死掉