概述
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是一种应用层协议,它是Web浏览器和Web服务器之间进行通信的标准协议。HTTP协议采用了客户端-服务端的请求-响应模式,客户端发送一个HTTP请求到服务器,服务器接收请求后返回一个HTTP响应。HTTP协议常用于Web应用中,如Web浏览器获取Web页面、发送电子邮件、进行购物等。
HTTP协议的工作流程如下:
客户端向服务端发送HTTP请求,请求中包括请求方法、URI、HTTP协议版本、请求头部和请求体。
服务端接收到HTTP请求后,根据请求方法、URI等信息处理请求,生成HTTP响应。
服务端将HTTP响应发送给客户端,响应中包括HTTP协议版本、状态码、响应头部和响应体。
客户端接收到HTTP响应后,根据状态码等信息处理响应,获取响应数据。
HTTP协议的请求方法包括GET、POST、PUT、DELETE、HEAD等,其中GET方法用于获取资源,POST方法用于向服务器提交数据等。HTTP协议的请求头部包括Accept、Content-Type、User-Agent等信息,请求体包括请求参数等数据。HTTP协议的响应状态码包括1xx、2xx、3xx、4xx、5xx等,常见的有200(请求成功)、404(请求的资源不存在)等。
HTTP协议是一种无状态协议,即每个请求都是独立的,服务器无法识别请求的来源和历史状态。为了解决这个问题,HTTP协议引入了Cookie和Session机制,通过在客户端和服务器之间传递状态信息实现状态的维护。
HTTP协议在Web应用中的重要性不言而喻,同时也存在着安全性、性能等方面的问题,如中间人攻击、跨站脚本攻击、性能瓶颈等,需要开发人员在实际应用中加以注意和解决。
三次握手,四次挥手
-
客户端向服务端发送一个SYN报文(一个数据包),来请求链接 确认客户端的发送能力正常,服务端的接受能力正常
-
服务端接受到SYN报文,并发送自己的ACK报文,表示自己接受到了客户端的SYN,然后把自己的SYN报文发出作为应答发送给客户端 确认服务端的发送能力正常,客户端接收能力
-
客户端接受到了SYN报文,再发送ACK报文,给予确认,双方已经建立起链接 确认客户端接收正常
-
客户端发送一个fin报文,停止发送数据,准备关闭TCP链接,等待服务端确认 提出关闭。
-
服务端接受到fin,并且会发送自己的ack报文,表示已经收到报文了,此时客服端TCP处于半关闭状态,结束了自己的发送,但能接受数据 收到关闭,半关闭,等待处理完数据。
-
等待服务端处理好所有报文之后,客户端想要断开链接,发送链接释放报文,等待客户端的确认 处理完数据,服务端表示可以关闭。
-
客户端接受到,发送fin报文,确定关闭链接' 客户端确认关闭
异常链接信息
出现大量CLOSE_WAIT
原因:
出现CLOSE_WAIT 状态的原因,是TCP四次挥手的第二次挥手被动关闭方的状态。 当服务端出现大量 CLOSE_WAIT 状态的连接的时候,说明服务端的程序没有调用 close 函数关闭连接。
解决方案:
【及时关闭未使用的连接】
出现大量time-wait
出现TIME_WAIT 状态的原因,是TCP四次挥手的第四次挥手主动关闭方的状态,可能如下原因导致:
1 HTTP没有使用长连接
HTTP没有使用长连接,就意味着服务器主动关闭时,每个都要进行四次挥手,而服务器端口、连接资源那么多,就会造成大量TIME_WAIT状态出现。
2 HTTP长连接超时
HTTP长连接是有超时时间的,超过这个时间,服务器就会主动关闭。 假设设置了 HTTP 长连接的超时时间是 60 秒,nginx 就会启动一个「定时器」,如果客户端在完后一个 HTTP 请求后,在 60 秒内都没有再发起新的请求,定时器的时间一到,nginx 就会触发回调函数来关闭该连接,那么此时服务端上就会出现 TIME_WAIT 状态的连接。
3 HTTP长连接的请求数量达到上限
当长连接的请求数量达到上限,服务器就会才去措施主动关闭一些连接。 比如对于一些 QPS 比较高的场景,比如超过 10000 QPS,甚至达到 30000 , 50000 甚至更高,如果 keepalive_requests 参数值是 100,这时 nginx 就会很频繁地关闭连接,那么此时服务端上就会出大量的 TIME_WAIT 状态。
影响
当连接处于TIME_WAIT状态时仍会占用系统资源(fd、端口、内存),过多的TIME_WAIT状态的连接会对系统的并发量造成影响。
1、对客户端的影响:
当客户端主动关系连接,出现大量的time_wait时,TIME_WAIT状态的连接就占用了一个本地端口。这样在TIME_WAIT状态结束之前,本地最多就能承受6万个TIME_WAIT状态的连接,就没有端口可用了,限制了客户端的并发率,同时,大量的TIME_WAIT连接同样会消耗客户端的内存。
2、对服务器的影响:
由于服务器一般只需要监听一个固定的端口,所以服务器所能支持的最大并发出数的上限取决于系统套接字描述符fd的大小,以及服务器的内存大小。当服务器主动关闭连接,产生time_wait时,每一个连接需要占用一定大小的内存资源,当TIME_WAIT 状态的连接过多时,会导致消耗的内存增加。
解决方案:
1、客户端(调整短链接为长链接)
HTTP 请求的头部connection设置为keep-alive,保持存活一段时间,目前浏览器已经这样处理了
2、服务器端
a允许time_wait状态的socket被重用;
b调整系统内核参数,缩减time_wait 时间,设置为 1 MSL(1MSL = 2 min)