HTTP

HTTP请求有三部分组成:

请求行

GET/images/logo.gif HTTP/1.1 基本由请求方法,URL,协议版本组成

首部

请求首部和响应首部

实体

HTTP/2

HTTP/2相比HTTP/1 大幅度提高了网页的性能

在HTTP/1 中,为了性能考虑,我们会引入雪碧图,将小图内联,使用多个域名等等的方式,这一些是因为浏览器限制了同一域名下的请求数量(Chrome下一般是限制六个连接),当页面中需要请求很多资源的时候,队头阻塞,其他资源会等待。

在HTTP/2中引入多路复用的技术,这个技术可以只通过一个TCP连接就可以传输所有的请求数据。多路复用很好的解决了浏览器限制同一域名下的请求数量的问题,同时也间接更容易实现全速传输,毕竟新开了一个TCP连接都需要慢慢提升传输速度。

二进制传输

HTTP/2中所有加强性能的核心点于此,在之前的HTTP版本中,我们是通过文本的方式传输数据,在HTTP/2中引入新的编码机制,所有传输的数据都会被分割,并采用二进制编码。

二进制具有健壮性(校验)

多路复用

在HTTP/2中,有两个重要的概念,分别是帧和流。

帧代表最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。

多路复用,就是在一个TCP连接中可以存在多条流,换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道数据哪个请求。通过这个技术,可以避免HTTP旧版本中的队头阻塞问题,极大提高传输性能

Header压缩

在HTTP/1中,我们使用文本的形式传输header,在header携带cookie的情况下,可能每次都需要重复传输几百到几千的字节。

在HTTP/2中,使用HPACK压缩格式对传输的header进行编码,减少了header的大小。并在两端维护了索引表,用于记录出现过的header,后面在传输过程中就可以传输已经记录过的header的键名,对端收到数据后就可以通过键名找到对应的值

服务端Push

在HTTP/2中,服务端可以在客户端某个请求后,主动推送其他资源

某些资源客户端是一定会请求的,这时就可以采取服务端push的技术,提前给客户端必要的资源,这样就可以相对减少一点延迟时间,当然在浏览器兼容的情况下你也可以使用prefetch

HTTP/3

虽然HTTP/2解决了很多之前旧版本的问题,但是它还是存在一个巨大的问题,虽然这个问题不是它本身造成的,而是底层支持的TCP。

因为HTTP/2使用了多路复用,一般来说同一域名下只需要使用一个TCP连接,当这个连接中出现了丢包的情况,那就会导致HTTP/2的表现情况反倒不如HTTP/1

因为在出现丢包的情况下,整个TCP都要开始等待重传,也就导致了后面的所有数据都被阻塞,但是对于HTTP/1来说,可以开启多个TCP连接,出现这种情况反倒只会影响其中一个连接,剩余的TCP连接还可以正常传输数据。

修改TCP不现实,所以Google就搞了一个QUIC协议,使用在HTTP/3上

QUIC 快速UDP互联网连接
自定义连接机制

TCP连接是由四元组标识的,分别是源IP,源端口,目的IP,目的端口,一旦一个元素发生变化,就需要断,重新连接。在移动互联情况下,当手机信号不稳定或者是WIFI和移动网络切换时,都会导致重连,从而进行再次三次握手,导致一定的时延。

这在TCP是没有办法的,但是基于UDP,就可以在QUIC自己逻辑里面维护连接的机制,不再以四元组标识,而是以一个64位的随机数作为ID来标识,而且UDP是无连接的,所以当IP或者端口变化,只要ID不变,就不要重新连接

自定义重传机制

TCP为了保证可靠性,使用序号和应答机制,但是他的算法中超时采样存在不准确的问题,例如:发送一个包,序号是100,发现没有返回,于是在发送一个100.过一阵返回一个ACK101,这时候客户端知道这个包肯定收到了,但是往返时间怎么计算,是ACK到达时间减去后一个100发送时间还是前一个100发送时间?事实上,第一种把时间算短,第二种把时间算长了

QUIC也有个序号,是递增的,任何一个序列号的包只发送一次,下一次就要加一。例如发送一个包,序号是100,发现没有返回;再次发送的时候,序号就是101了。如果返回的ACK100,就是对第一个包的相应,如果返回ACK101就是对第二个包的相应,那么往返时间RTT计算相对准确。

QUIC是怎么知道100和101包发送的内容相同,里面有一个offset概念。是一个偏移量,通过它就能查看数据发送到了呢?这样只要这个offser的包没有来,就要重发,如果来了,按照offset拼接,

无阻塞的多路复用

有了自定义的连接和重传机制,我们就可以解决上面HTTP/2多路复用的问题

和HTTP/2一样 QUIC连接上可以创建多个stream,来发送多个HTTP请求,但是QUIC是基于UDP的,一个连接上的多个stream之间没有依赖,这样加入stream2丢了一个UDP包,后面跟着stream3的一个UDP包,虽然stream2的那个包需要重传,但是stream3的包无需等待,就可以发送给用户

自定义流量控制

TCP流量控制是通过滑动窗口协议,QUIC的流量控制也是通过改变。但是QUIC的窗口是适应自己的多路复用机制的,不但在一个连接上控制窗口,还在一个连接中的每个stream控制窗口

HTTPS

HTTP+加密+认证+完整性保护=HTTPS

WebSocket

使用浏览器进行全双工通信的WebSocket协议
特点
推送功能

服务器向客户端推送数据的功能

减少通信量

只要建立连接,就希望一直保持连接状态,和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很少,通信量也相应减少

为了实现WebSocket通信 在HTTP连接建立之后,需要完成一个握手的步骤

握手-请求

需要HTTP的Upgrade首部字段,告知服务器通信协议发生改变,已到达握手的目的

握手-响应

对于之前的相应,返回101

连接建立以后使用WebSocket独自帧