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:等待所有分组死掉