zhangsanshi / issue-blog

It's a blog rather than issue
0 stars 0 forks source link

HTTP2 #25

Open zhangsanshi opened 7 years ago

zhangsanshi commented 7 years ago

HTTP2

本文希望探讨一下 HTTP2 做出的一些修改以及新增功能以及原因,很多东西翻译而来的,原则上建议是阅读规范本身。

基本概念

HTTP

超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协议。 HTTP的URL由 "http://" 起始且默认使用端口80

HTTPS

超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,也被称为HTTP over TLS,HTTP over SSL 或 HTTP Secure) URL由“https://”起始且默认使用端口443

版本

1. HTTP 0.9

已过时。只接受GET一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持POST方法,因此客户端无法向服务器传递太多信息。

2. HTTP/1.0

这是第一个在通讯中指定版本号的HTTP协议版本,至今仍被广泛采用,特别是在代理服务器中。

3. HTTP/1.1

持久连接被默认采用,并能很好地配合代理服务器工作。还支持以管道方式在同时发送多个请求,以便降低线路负载,提高传输速度。

4. HTTP/2

HTTP/2是HTTP协议自1999年HTTP 1.1发布后的首个更新,主要基于SPDY协议。它由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组进行开发。该组织于2014年12月将 HTTP/2 标准提议递交至IESG进行讨论,于2015年2月17日被批准。HTTP/2 标准于2015年5月以 RFC 7540 正式发表。

什么是 HTTP/2

HTTP/2 没有重写协议,HTTP 方法、状态码、语义等,可以像使用 HTTP/1.x 一样使用它。协议本身关注的重点在性能,终端用户的等待时间,网络和服务器资源的使用。致力于数据从客户端到服务器传输使用一个连接。 协议基于 SPDY 开发的,同时在开发的过程中吸收接纳了社区的很多建议和改善。

规范

HTTP/2 包含了下面两个规范:

正文

首先来看一点是,HTTP/2 基于 SPDY 协议开发的,所以我们需要先了解一下 SPDY。

SPDY

SPDY 是一个在万维网用于低延迟传输内容的协议。SPDY 有两个协议层。较低层是通用成帧层,其可以在用于多个并发流的多路复用,优先化和压缩数据通信的可靠传输(可能的TCP)之上使用。该协议的上层提供了一个类似 HTTP 的语义,与现有的 HTTP 应用服务器兼容。

HTTP 实现的瓶颈之一是 HTTP 依赖多个连接用于并发。这会导致一些问题,包括建立连接产生的额外的往返,慢启动延迟,客户端的连接限制等。这就是为什么需要减少连接到单个服务器。HTTP pipelining 有一些帮助的,但只实现了部分复用。此外,pipelining 已被证明在现有浏览器由于中间人干扰的原因而不可部署(链接,参考4也有答案)。

SPDY 添加了一个帧层用于多路复用,在一个单独的 TCP 连接(或者其他可靠的传输流)里合并所有的流。这个帧层对于类似 HTTP 请求响应流可以说是最优的,因为它使得 web应用 作者可以不做任何事情或者只做很小的改动就可以让运行在 HTTP 上面的应用,同时运行在 SPDY 上面。

SPDY 提供了对 HTTP 的四个改进:

  1. 多路复用请求:单个 SPDY 连接同时发出 N 个请求,不会对请求的数量做限制
  2. 优先请求:客户端可以优先请求某些资源。这消除了高优先级的非关键资源被 pending 的情况下会造成网络拥堵的问题
  3. 压缩头: 客户端在 HTTP headers 里发送大量冗余数据。因为单个网页可能会请求 50 或 100 个子请求,所以这个数据就意义重大了
  4. 服务端推送流: 服务端推送允许推送内容到客户端,而不需要客户端发出一个请求,当然客户端可以拒绝,比如说已经缓存该资源

HTTP2 基于 SPDY 做的改进

HTTP2 使用了 HPACK 规范,它是一种高效的表示 HTTP 报头字段的压缩格式。 其他未知,具体参考协议。。。

HPACK

在HTTP / 1.1(参见RFC7230)中,头字段未压缩。随着网页发展到需要几十到几百个请求,这些请求中的冗余报头字段不必要地消耗带宽,等待时间也越来越长。 SPDY 最初通过使用 DEFLATE 格式压缩标题字段来解决这种冗余,这在有效地表示冗余报头字段方面非常有效。然而,该方法暴露了CRIME(压缩率使信息很容易泄露)攻击(参见CRIME)所示的安全风险。 该规范定义了 HPACK,它是一种新的压缩器,它消除了冗余报头字段,限制了已知安全攻击的脆弱性,并且具有在受限环境中使用的有限内存要求。当然其还有一些潜在安全问题。 HPACK 格式是有意简单和不灵活的。这两个特性降低了由于实现错误导致的互操作性或安全性问题的风险。没有定义可扩展性机制;只有通过定义完全替换才能更改格式。 这个规范就是上面 HTTP2 包含的规范之一。

思考

  1. HTTP2 利用同一个 TCP 的情况下,会节省哪些时间
  2. 目前优化手段,将资源分布在多个服务器、合并css、合并js、背景图等,在启用 HTTP2 的情况下有什么影响
  3. HTTP1.1 队首阻塞,在启用 HTTP2 的情况下,情况会有所缓解吗
  4. 客户端严格设置请求优先级,会导致什么问题,比如说在请求高优先级慢请求的情况下
  5. 对于服务端可以主动推送资源,有没有什么好的玩法

参考

  1. https://http2.github.io
  2. https://tools.ietf.org/html/draft-mbelshe-httpbis-spdy-00
  3. https://en.wikipedia.org/wiki/HTTP_pipelining
  4. http://dev.chromium.org/spdy/spdy-whitepaper
  5. http://httpwg.org/specs/rfc7541.html
  6. RFC7540
  7. RFC7541
  8. https://datatracker.ietf.org/wg/httpbis/charter/
  9. https://imququ.com/post/protocol-negotiation-in-http2.html

结后语

写这个花了好久,中间有事又给放弃了一段时间,想着自己都快把读的内容都给忘了,最终还是润润色,就拿出来了,其实看再多的文章,不如对着规范读,再实践,规范我只是阅读部分,想写的更多也写不出来了,实践也没来得及,希望后续能补。