早期的 HTTP协议,如HTTP0.9之前也被称为是“无连接”的协议。不会与服务器保持长期的连接状态,所以也称为短连接,短连接每一次的请求都需要重新建立TCP连接,有10个请求就需要建立10次TCP连接,这个效率,可想而知是非常低的
到Http1.0就出现了长连接的通信方式,解决了短连接多次建立TCP连接的痛点,现在Http1.1基本都是默认开启Connection: keep-alive 长连接的, TCP连接只要建立一次,后续的请求都复用该通道,不用再重新建立TCP通道,效率大大提升
需要注意的是:不管是http短连接还是长连接,它们的请求和响应都有有序的,都是等上一次请求响应后,才接着下一个请求的,那能不能不等第一次请求回来,我就开始发第二次请求呢?这就引出http管道化了
http的管道化和非管道化:
在长连接的基础上,HTTP1.1进一步地支持在持久连接上使用管道化(pipelining)特性,这是相对于keep-alive连接的又一性能优化。在相应到达之前,可以将多条请求放入队列,当第一条请求发往服务器的时候,第二第三条请求也可以开始发送了,不用等到第一条请求响应回来,在高延时网络条件下,这样做可以降低网络的环回时间,提高性能。
非管道化与管道化的区别示意:
http队首阻塞:
简单理解就是需要排队,队首的事情没有处理完的时候,后面的人都要等着。
队头阻塞”与短连接和长连接无关,而是由 HTTP 基本的“请求 - 应答”机制所导致的。因为 HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。
而http的队首阻塞,在管道化和非管道化下,表现是不同的
http1.0的队首阻塞 ( 非管道化下 ) :
可见,http1.0的队首组塞发生在客户端。
http1.1的队首阻塞 ( 管道化下 )
下图演示的是,第一个响应延迟后,后续响应跟着延迟
可见,应用管道化技术后,http1.1的队首阻塞发生在服务器端。
HTTP队头阻塞 的解决方法
并发TCP连接:
我们知道对于一个域名而言,是允许分配多个长连接的,那么可以理解成增加了任务队列,也就是说不会导致一个任务阻塞了该任务队列的其他任务,在RFC规范中规定客户端最多并发2个连接,不过实际情况就是要比这个还要多,Chrome中是6个,说明浏览器一个域名采用6个TCP连接,并发HTTP请求
域名分片
顾名思义,我们可以在一个域名下分出多个二级域名出来,而它们最终指向的还是同一个服务器,这样子的话就可以并发处理的任务队列更多,也更好的解决了队头阻塞的问题。
举个例子,比如baidu.com,可以分出很多二级域名,比如zhidao.baidu.com,xxx.baidu.com 这样子就可以有效解决队头阻塞问题。
利用HTTP2的多路复用解决:
对于HTTP1.1中管道化导致的请求/响应级别的队头阻塞,可以使用HTTP2的多路复用解决。
http2中将多个请求复用同一个tcp通道中,通过二进制分帧并且给每个帧打上流的 ID 去避免依次响应的问题,对方接收到帧之后根据 ID 拼接出流,这样就可以做到乱序响应从而避免请求时的队首阻塞问题,
当然,即使使用HTTP2,如果HTTP2底层使用的是TCP协议,仍可能出现TCP队头阻塞。
下图为http2多路复用,解决服务器响应时http队首阻塞演示
总结:
HTTP队头阻塞
对于每一个HTTP请求,会被放入一个任务队列中串行执行,一旦队首任务请求太慢时,就会阻塞后面的请求处理
有非管道化和管道化,两种阻塞方式:
非管道化:完全串行执行,请求->响应->请求->响应…,后一个请求必须在前一个响应之后发送,发生在客户端,http请求阻塞
管道化:请求可以并行发出,但是响应必须串行返回。后一个响应必须在前一个响应之后。原因是,没有序号标明顺序,只能串行接收,发生在服务端,http响应阻塞
管道化请求的致命弱点:
会造成队头阻塞,前一个响应未及时返回,后面的响应被阻塞
请求必须是幂等请求,也就是只有GET和HEAD请求才能管道化,不能修改资源。因为,意外中断时候,客户端需要把未收到响应的请求重发,非幂等请求,会造成资源破坏。
由于这个原因,目前大部分浏览器和Web服务器,都关闭了管道化,采用非管道化模式。
无论是非管道化还是管道化,都会造成队头阻塞(请求,响应阻塞)。
解决http队头阻塞的方法:
额外的:
http2中的多路复用和http1.1中的keep-alive有什么区别?
共同点: 都可以复用同一条TCP通道
区别:
https多路复用:并发请求,非阻塞的
详细描述:
keep-alive虽然可以复用同一条TCP通道,但必须等到服务端响应了前一次请求,才能发起第二次请求 ->阻塞。 按顺序发送请求,按顺序接收请求,这样接收端才不会乱掉。从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接,Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间
http2 的多路复用可以在一条TCP通道同时发送多个请求,不一定要按照顺序,非阻塞的,先响应先回来,响应式时也不用等上一个请求先响应,这些请求都有唯一标识,所以可以无序。
客户端与服务端之间建立通信需要经过该三次握手:客户端建立连接(发送syn报文)->服务端发送确认信息(发送syn+ack报文)->客户端接收确认信息。因此通过tcp建立了客户端与服务端的连接。
http通信通过tcp建立连接一般都是短连接,客户端与服务器之间建立了一次通信后就要断开连接,当再次需要进行通信的时候就要再次通过tcp建立连接.
通过tcp建立Http长连接,就解决了短连接的弊端,当建立了客户端和服务器端的连接后,就会保持这个连接,但是不会断开,后续通信可继续使用这个长连接。但是长连接会对服务器端造成非常大的压力,因为长连接不关闭的话会越来越多。解决这种风险可以设置最大长连接数,服务器端也可以关闭一些长时间无操作的连接。
短轮询是建立在http通信的基础上。当服务器端的数据在实时更新想要向客户端推送时,就会用到轮询这种方式。因为客户端只能主动向服务器端发送请求获取数据,但是要服务端主动发送数据给客户端,就可以在客户端不断的发送请求给服务器端,服务器端不管有没有数据都会返回数据。保持客户端不断发送请求的方法是设置一个定时器不断调用某个函数.
然而短轮询的缺点也显而易见,这样不断的请求数据就会造成服务器端的压力,并且如果设置超时过短就会获得脏数据.
长轮询是对短轮询的一种提升,当客户端不断地向服务器端请求数据的时候,若有数据则返回,没有数据返回的情况都要hold on ,直到timeout。这种解决办法一定程度上解决了服务器端的压力,但是如果进程过多,也会成为问题.
这是最近对浏览一些博客最基本的了解,以后如果有更深层次的了解将会继续修改。
在网络层有IP协议,ICMP协议,ARP协议,RARP协议和BOOTP协议.在传输层中有:TCP协议与UDP协议.
在应用层有:通过TCP协议来通信的应用层协议包括FTP,HTTP,TELNET,SMTP协议. 通过UDP协议来通信的应用层协议包括DNS,TFTP等
连接->数据传输->关闭连接
HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,单任务结束后就中断连接.也可以这样说:短连接是指Socket连接后发送后接收完数据后马上断开连接.
连接->传输数据->保持连接->传输数据->….->关闭连接
长连接指建立socket连接后不管是否使用都保持连接,但安全性较差.
http的长连接
HTTP也可以建立长连接的,使用Connection:keep-alive,HTTP1.1默认进行持久连接,HTTP1.1和HTTP1.0相比较而言最大的区别就是添加了持久连接支持(貌似最新的http1.0可以显示的指定keep-alive)但还是无状态的,或者说是不可信任的.
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况.每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接在操作的话那么处理时间会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用再次建立连接.例如即使通讯环信底层用的就是长连接聊天过程中为了保证消息的实时性,保持长连接进行会话!
而web网站的http服务一般用短连接,因为长连接对于服务端来说会耗费一定的资源,而像web网站这样频繁成千上万甚至上亿客户端的连接用短连接会更省资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,并发数会很大,这样后台服务器有承受很大的压力,所以这种情况小用短连接会比较好.
Socket是应用层与TCP/IP协议通讯的中间软件抽象层,它是一组接口,在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/IP组协议隐藏在了socket接口后面,对用户来说简单的接口就是全部,让socket去组织数据,以符合指定的协议.
主机A的应用程序要和主机B的应用程序进行通信,必须通过socket建立连接,而建立socket连接必须通过底层的TCP/IP协议建立TCP连接,建立TCP连接需要底层IP协议来寻址网络中的主机.我们知道网络中的IP协议可以帮助我们根据IP地址来找到目标主机但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过TCP和UDP的地址也就是端口号来指定,这样就可以通过socket实例唯一代表一个主机上的一个应用程序的通信链路了.
(1)第一次握手:Client(客户端)将标识位SYN(发起一个新连接)置为1,随机产生一个(序号:发送数据对其标识)seq=J,并将该数据发送给server(服务器),Client(客户端)进入SYN_SENT状态,等待Server确认.
(2)第二次握手:Server收到数据包后由SYN=1知道Client请求建立连接,Server将SYN和ACK都置为1,ack=J+1.随机产生一个seq=k,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态.
(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标识位ACK置为1,ack=k+1并将数据包发送给Server,Sever检查ack是否为k+1,ACK是否为1,如果正确则建立连接Client和server进入ESTABLISHED状态,完成三次握手,随后Client和Server之间可以开始传输数据了.
(1)第一次挥手:Client发送一个FIN(释放一个连接),用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK(确认序号有效)状态.
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
Q1 : HTTP Socket TCP UDP都是什么?
HTTP 全称是超文本传输协议,是一个应用层的协议。用于客户端和服务端之间进行通讯。
TCP/UDP 都是传输层协议。TCP是可靠的,我们常说的三次握手连接,四次握手断开都是说的TCP。而UDP是不可靠的。
Socket 则是从传输层抽象出来的接口层。
Q2 : HTTP连接和Socket连接有什么区别?分别在什么情况下使用?
HTTP 是基于TCP的短连接。需要经过三次握手建立连接,且无法保持始终连接。
Socket 是长连接。基于TCP的Socket连接,一旦建立三次握手,除非一方主动断开,否则连接状态一直保存。也可以基于UDP进行Socket连接。
HTTP连接,服务端无法主动发消息,采用的是'请求-响应'机制。客户端没有发消息给服务端,服务端无法推送消息给客户端。
Socket连接,一方可以随时向另一方发起会话。
双方不需要时刻保持连接在线用HTTP。eg : 客户端资源获取、上传文件等。
即时通讯应用需要用Socket连接。eg : 微信、苹果的APNs等。
Q3 : HTTPS是什么?和HTTP有什么区别?
HTTPS就是HTTP加上SSL/TLS。TLS(Transport Layer Security)传输层安全协议,作用是在传输层对网络连接加密。SSL就是TLS的前身。
HTTP端口是80,是无状态的。HTTPS端口是443,是可以进行加密传输、身份认证的网络协议。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)