# http 1.0

  • 链接无法复用,即不支持持久链接:

浏览器每次请求都会和服务器经过三次握手以及慢启动[1]来建立TCP连接, 服务器完成请求处理后立即断开连接,而且不追踪每个浏览器的历史请求

慢启动

TCP开始传输数据或发现数据丢失并且重发时,首先慢慢的对网络实际容量开始试探,避免因为发送过量数据导致阻塞

  • 线头阻塞

请求队列的第一个请求因为服务器正忙或者请求格式问题等其他原因,导致后面的请求被阻塞

# http 1.1

  • 支持持久链接

在request和response中的header内的connection属性,通过设置是close或Keep-Alive进行控制

一个TCP链接可以传送多个http请求和响应,减少TCP建立链接和关闭链接的消耗。

另外,http1.1运行客户端不等待上一个请求结果返回,就你可以发出下一个请求, 但是服务器必须按照收到客户端请求的先后顺序依次返回响应结果,避免客户端无法区分每次请求的响应内容

  • 支持http管道

不使用管道的http请求,在使用持久链接时,必须严格满足先进先出的队列顺序(FIFO)。

管道可以让我们吧FIFO队列从客户端(请求队列)迁移到服务端(响应队列),即客户端可以并行,服务端可以串行。 客户端可以不用等待前一个请求返回,发送请求,但服务端必须顺序的返回客户端的请求响应结果

缺点:

  1. 一个请求响应阻塞,就会阻塞后续所有请求
  2. 并行请求请求时,服务器必须缓冲管道中的响应,从而占用服务器资源,如果有个响应非常大,则很容易形成服务器的受攻击面
  3. 响应失败可能会终止TCP链接,从而强迫客户端重新发送对所有后续资源的请求,导致重复处理
  4. 可能会存在中间代理,因此检测管道兼容性,确保可靠性很重要
  5. 如果中间代理不支持管道,那它可能会中断连接,也可以会把所有的请求串联起来
  • 使用多个TCP链接

http1.1在客户端排队所有请求,然后通过一个TCP持久链接,一个接一个的发送请求(如果有http管道还必须等待服务端的顺序返回结果)。 实际中,浏览器开发时会允许打开N个TCP链接。

优点:

  1. 客户端可以并行发送最多N个请求
  2. 服务器可以并行处理最多N个请求
  3. 第一个往返可以发送的累计分组数量(TCP cwnd)增长为原来的N倍

缺点:

  1. 更多的套接字会占用客户端、服务器以及代理的资源,包括内存缓冲区和CPU的时钟周期
  2. 并行TCP流之间竞争共享的带宽
  3. 由于处理多个套接字,实现复杂度更高
  4. 即使并行TCP流,应用的并行能力也受限制
  • 增加了请求头和响应头来扩充功能

  • 域名分区

将原来集中到一个服务器上的资源分布到多个服务器上,这样可以突破浏览器的链接限制(一般是6个),提高并行能力

缺点:

  1. 每多一台主机就要多一次DNS查询,每多一个套接字就会消耗两端的一些资源
  2. 必须手工分离一台主机上的资源到其他主机
  • http的header优化

目前所有的header请求都是以美元经过压缩的纯文本的形式发送(通常有600~1000字节),而通常用于http请求的body却很少(10~200字节), 使用了cookie之后,这样的矛盾会更加突出,因此要减少header的数据

  • 减少连接次数

将需要多次请求才能获取的文件或资源组合成一个,通过一次请求获取。 这样可以减少协议的开销,也间接地将服务器的管道思维移植到了客户端。

缺点:

  1. 增加了复杂度,给缓存带来了负担
  2. 页面的分步显示改成了一次显示,影响用户体验
  • 嵌入小的文件

将资源嵌入文档(通过URL嵌入图片、音频或PDF),可以减少请求次数,一般只考虑1~2KB的资源。 嵌入资源会作为页面的一部分一次返回,如果多个页面中都嵌入了同样的资源了,那么这个资源会随着每个页面的加载而被加载, 从而增大了每个页面的总体大小,如果嵌入资源被更新,那么客户端只能重新获取有效的资源

# http 2.0