29 | HTTP/1:HTTP 性能优化

超文本传输协议 HTTP/0.9

HTTP/0.9 是在 1991 年提出。
主要用于学术交流-在网络之间传递 HTML 超文本内容,所以被称为超文本传输协议(HyperText Transfer Protocol)
过程是:客户端根据 IP 地址、端口号和服务器建立 TCP 连接,建立连接后,发送一个 GET 请求行消息来获取 html,服务器接收到这个 Get 请求,将数据以 ASCII 字符流返回给客户端,html 传输完成,断开连接。
特点是:只有一个请求行,没有 HTTP 请求头和请求体;服务器也没有返回头信息,只有返回的数据;返回的文件内容是以 ASCII 字符流来传输的。

关键词:1991 年、学术交流、Get、超文本内容、ASCII

被浏览器推动的 HTTP/1.0

新兴网络的发展,浏览器需要展示的内容不单单是 HTML 文件,还有 JS、CSS、图片、音频、视频等不同类型的文件,也就是说 HTTP1.0 的核心诉求就是要支持多种类型的文件下载,且文件格式不再局限于 ASCII 编码了。
为了满足多种类型文件的传输,HTTP/1.0 引入了请求头和响应头
请求头的内容有:服务器返回的文件类型、文件压缩方式、提供什么语言文件、文件的具体编码:

1
2
3
4
accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh

除了对多文件的增强外,还根据实际需求引入了几个新增的典型特性:

  • 引入了**状态码 **
  • 为了减轻服务器压力,HTTP/1.0 提供了 Cache 机制,用来缓存下载过的数据
  • 在请求头中加入了用户代理的字段(为了统计客户端的信息–比如 Windows 和 MacOS 用户数量为多少)

HTTP/1.0 关键词:多种类型文件、请求头和响应头、状态码、Cache 机制、用户代理

缝缝补补的 HTTP/1.1

改进持久性连接

随着发展,一个页面可能包含几百个外部资源文件,为了解决每次下载都需要建立 TCP 连接,HTTP/1.1 中增加了持久性连接的方法,特点是可以在一个 TCP 连接上传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么持久性连接就会使得该 TCP 连接一直保持。
然后,这么做就减少了服务器的负担,提升了 HTTP 的请求时长,他的持久性连接是默认开启的,如果想关闭通过 Connection:close。
目前,浏览器对于同一个域名,默认允许建立 6 个 TCP 持久连接。
如果想增加 TCP 的连接,可以使用一种叫做域名分片的技术:把该站点下面的资源放在多个域名下。

不成熟的 HTTP 管线化

如果 TCP 通道中的某个请求因为某些原因没有及时返回,那就会阻塞后面的所有请求,这就是著名的队头阻塞问题。
HTTP/1.1 使用了管线化技术,但是不成熟。
HTTP/1.1 的管线化技术是将多个 HTTP 请求整批发送给服务器的技术。虽然整批发送了请求,但是服务器依然需要根据请求顺序来回复浏览器的请求。

提供虚拟主机的支持

随着虚拟主机发展,一台主机可以绑定多个虚拟主机,每个虚拟主机都可以有自己的单独域名。
于是,HTTP/1.1 的请求头中添加了 Host 字段,用来表示当前的域名地址。

对动态生成的内容提供了完美支持

在 HTTP/1.0 那会,浏览器根据响应头中设置的服务器告诉的数据大小来进行数据的接收,但随着服务器端发展,服务器返回的内容为动态生成,也就在传输数据的时候不知道最终的数据大小是多少,这个时候浏览器也就不知道到底接收多少数据。
于是,HTTP/1.1 引入了Chunk transfer机制,服务器将数据分割成任意大小的数据块,每个数据块发送时会附上上个数据的长度,最后一个使用零长度来作为发送数据完成的标志,于是也就提供了对动态内容的支持。

客户端 Cookire、安全机制

添加 Cookie。

HTTP/1.1 关键词:改进持久性连接、添加了 Host 字段、Chunk transfer 机制、Cookie、解决队头阻塞问题使用用不成熟的管线化技术。

30 | HTTP/2:如何提升网络速度?

HTTP/1.1 的主要问题

HTTP/1.1 的核心问题是:对宽带的利用率不理想
宽带是指每秒最大能发送或者接收的字节数,我们把每秒能发送的最大字节数称为上行宽带,每秒能接受的最大字节数称为下行宽带。出现宽带利用率的问题,主要有三个原因导致:

  • TCP 的慢启动:慢启动是 指刚开始的时候 TCP 协议它会采用一种非常慢的速度去发送数据,然后慢慢加快发生数据的速度,这是 TCP 这个协议为减少网络阻塞的一种策略,我们无法改变。
  • 开启了多条 TCP 连接,那么这些连接会竞争固定的宽带,会影响关键资源的下载速度。
  • HTTP/1.1 的队头阻塞问题:持久化连接可以共用一个通道,且同一时刻只能处理一个请求,请求没结束前,其它请求只能处于阻塞状态。

HTTP/2 的多路复用

针对 HTTP/1.1 的问题,队头阻塞是由于 TCP 本身机制导致的,所以 HTTP/2.0 就针对了如何规避 TCP 的慢启动和 TCP 连接之间的宽带竞争下手。
HTTP/2 的解决思路是一个域名只使用一个TCP 长连接来传输数据,这样整个页面的资源下载只需要一次慢启动,且避免了多个 TCP 连接竞争宽带的问题。
当然如果一个域名使用一个TCP长连接,那么针对队头阻塞问题,请求完一个请求再去发送另一个请求无疑是非常慢的,所以 HTTP/2 需要实现资源的并行请求:也就是任何时候都可以将请求发送给服务器。

一句话总结 HTTP/2 为:一个域名只使用一个 TCP 长连接和解决队头阻塞问题。 也就是最具颠覆性的多路复用机制
多路复用机制的过程:是说每一个请求都一有一个对应的ID,服务端拿到这些请求的ID和内容后,自行决定哪些是关键资源,然后立即将关键资源返回。好处就是优先处理关键资源请求。

多路复用的实现

HTTP/2添加了一个二进制分帧层。
然后客户端发送过来的请求,经过这个层,进行处理给他们编号(帧),然后发送给服务器。
服务器接收到请求,将相同编号的进行合并成一条完整信息进行一次处理,然后再返回给这个二进制分帧层。
二进制分帧层再将响应数据拆开,然后返回给客户端。

HTTP/2其他特性-基于二进制分帧层

  • 可以设置请求的优先级
  • 服务器推送:HTTP2可以直接将数据提前推送至客户端
  • 头部压缩:对请求头和响应头做了压缩。

其它

HTTP/2没必要使用雪碧图了。

31|HTTP/3:甩掉TCP、TLS 的包袱,构建高效网络

本文的学习目录为:先分析HTTP2的主要缺陷三条,然后解决方法一条的展开:

TCP的队头阻塞

TCP的队头阻塞是由于TCP是为了单连接而设计的,这样的设计导致的是:在传输数据过程中如果发生丢包,那么TCP连接就会处于暂停状态,等待重新传过来的包。
在TCP的传输过程中,由于单个数据包的丢失而造成的阻塞称为TCP上的队头阻塞。
相对于HTTP/1.1发生丢包还比较看的过去,因为HTTP/1.1为每个域名开启了6个TCP连接,其中一个发生丢包不会影响其它五个,而对HTTP2来说,由于只有一个TCP连接通道,若任何一次请求发生丢包,则会阻塞TCP连接中的所有请求。
然后通过HTTP2与HTTP1.1比较,当这个丢包率超过了2%的时候,HTTP1.1的传输效率反而比HTTP2要好。

TCP建立连接的延时

除了TCP队头阻塞,TCP握手也是影响传输效率的一个重要因素。
网络延迟又称为RTT(Round Trip Time),指的是浏览器发起一个数据包到服务器,服务器再返回数据包到浏览器的整个往返时间。
建立TCP连接的时候,三次握手使得需要消耗完1.5个RTT才能进行数据传输,如果有TLS连接,还需要1~2个RTT。也就是说,传输数据之前就需要花掉3~4个RTT,而一个RTT的时间可能是10毫秒以内,也就是总共需要消耗30~40毫秒,如果与服务器相隔较远,那么可能需要300-400毫秒,这个时候看到页面的效率就变慢了。

TCP协议僵化

目前掌握来看,HTTP2 的主要问题有TCP的队头阻塞和建立连接延迟的缺点,然后想要改进TCP协议才进行升级,比较困难,原因主要是因为中间设备的僵化
为了保障互联网的正常工作,我们需要在各处搭建各种设备,这个设备就是指中间设备,包括路由器、防火墙、交互机等,这些中间设计使用了大量TCP的特性且更新较少,因此如果客户端升级TCP协议,这些中间设备由于升级的困难,因此行不通。
除了中间设备外,操作系统也是TCP协议僵化的一个主要原因。因为TCP协议都是通过操作系统内核实现的,应用程序只能使用而不能修改。

QUIC协议

解决思路是绕过TCP协议,发明一个TCP和UDP之外的新的传输协议,HTTP/3就选择了一个折衷的方法–基于UDP协议实现类似于TCP的多路数据流、传输可靠性等功能,这套功能就称为QUIC协议。
QUIC协议集合了以下几个功能点:

  • 实现了类似TCP的流量控制、传输可靠性的功能。
  • 集成TLS加密功能:最重要的是减少了握手花费的RTT个数。
  • 实现了HTTP/2的多路复用功能。
  • 实现了快速握手功能。