HTTP

HTTP/2

HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能。

在 HTTP/1 中,为了性能考虑,我们会引入雪碧图、将小图内联、使用多个域名等等的方式。这一切都是因为浏览器限制了同一个域名下的请求数量(Chrome 下一般是限制六个连接),当页面中需要请求很多资源的时候,队头阻塞(Head of line blocking)会导致在达到最大请求数量时,剩余的资源需要等待其他资源请求完成后才能发起请求。

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

二进制传输

在之前的 HTTP 版本中,我们是通过文本的方式传输数据。在 HTTP/2 中引入了新的编码机制,所有传输的数据都会被分割,并采用二进制格式编码。

多路复用

在 HTTP/2 中,有两个非常重要的概念,分别是帧(frame)流(stream)

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

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

请求优先级

把HTTP消息分为很多独立帧之后,就可以通过优化这些帧的交错和传输顺序进一步优化性能。

服务器可以根据流的优先级控制资源分配(CPU、内存、宽带),而在响应数据准备好之后,优先将最高优先级的帧发送给客户端。浏览器可以在发现资源时立即分派请求,指定每个流的优先级,让服务器决定最优的响应次序。这样请求就不用排队了,既节省了时间,又最大限度的利用了每个连接。

首部压缩

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

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

服务器推送

HTTP2.0新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确的请求。

在HTTP2.0中,服务端根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。比如,客户端请求stream 1(/page.html)。服务端在返回stream 1的消息的同时推送了stream 2(/script.js)和stream 4(/style.css)

HTTP/3

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

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

基于这个原因,Google 就更起炉灶搞了一个基于 UDP 协议的 QUIC 协议,并且使用在了 HTTP/3 上,当然 HTTP/3 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了 QUIC,接下来我们就来学习关于这个协议的内容。

QUIC

QUIC 虽然基于 UDP,但是在原本的基础上新增了很多功能,比如多路复用、0-RTT、使用 TLS1.3 加密、流量控制、有序交付、重传等等功能。

多路复用

虽然 HTTP/2 支持了多路复用,但是 TCP 协议终究是没有这个功能的。QUIC 原生就实现了这个功能,并且传输的单个数据流可以保证有序交付且不会影响其他的数据流,这样的技术就解决了之前 TCP 存在的问题。

并且 QUIC 在移动端的表现也会比 TCP 好。因为 TCP 是基于 IP 和端口去识别连接的,这种方式在多变的移动端网络环境下是很脆弱的。但是 QUIC 是通过 ID 的方式去识别一个连接,不管你网络环境如何变化,只要 ID 不变,就能迅速重连上。

0-RTT

通过使用类似 TCP 快速打开的技术,缓存当前会话的上下文,在下次恢复会话的时候,只需要将之前的缓存传递给服务端验证通过就可以进行传输了。

纠错机制

假如说这次我要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。

当出现其中的非校验包丢包的情况时,可以通过另外三个包计算出丢失的数据包的内容。

当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了。

状态码

  • 1xx 消息响应
  • 2xx 成功响应
  • 3xx 重定向消息
  • 4xx 客户端错误响应
  • 5xx 服务端错误响应

适用场景

  • 100:客户端在发送 POST 数据给服务器前,征询服务器情况,看服务器是否处理 POST 的数据,如果不处理,客户端则不上传 POST 数据,如果处理,则 POST 上传数据。常用于 POST 大数据传输
  • 206:一般用来做断点续传,或者是视频文件等大文件的加载
  • 301:永久重定向会缓存。新域名替换旧域名,旧的域名不再使用时,用户访问旧域名时用 301 就重定向到新的域名
  • 302:临时重定向不会缓存,常用 于未登陆的用户访问用户中心重定向到登录页面
  • 304:协商缓存,告诉客户端有缓存,直接使用缓存中的数据,返回页面的只有头部信息,是没有内容部分
  • 400:参数有误,请求无法被服务器识别
  • 403:告诉客户端禁止访问该站点或者资源,如在外网环境下,然后访问只有内网 IP 才能访问的时候则返回
  • 404:服务器找不到资源时,或者服务器拒绝请求又不想说明理由时
  • 503:服务器停机维护时,主动用 503 响应请求或 nginx 设置限速,超过限速,会返回 503
  • 504:网关超时

常见的状态码

下面是常见的 HTTP 状态码:

  • 200 - 请求成功
  • 204 - 请求处理成功,但没有任何资源可以返回给客户端,一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
  • 301 - 资源(网页等)被永久转移到其它URL
  • 302 - 资源(网页等)被临时转移到其它URL
  • 400 - 服务器端无法理解客户端发送的请求,请求报文中可能存在语法错误。
  • 401- 请求要求用户的身份认证,一般是指未被授权,请进行相关的身份验证,比如登录
  • 404 - 请求的资源(网页等)不存在,常常是代码错误,路径错误,网址输入错误或者是网络不佳,网络拥堵等等造成的
  • 418 - 服务器检测请求头,检查出你的操作疑似爬虫,总而拒绝,返回418
  • 500 - 内部服务器错误,无法完成请求
  • 503 - 抱歉,我现在正在忙着。该状态码表明服务器暂时处于超负载或正在停机维护,现在无法处理请求。

ping

ping raw.githubusercontent.com

通过 ping 命令,我们可以获取计算机到目标服务器的网络连接状态,同时也可以获取目标服务器的 IP 地址。