HTTP 2.0 将会使应用程序更快、更简单、并且更健壮。HTTP 2.0的首要目标通过请求-响应多路复用,报头压缩,优先级控制、服务器推送来减少延时。为了达到这个目的,HTTP 2.0需要支持大量的路I量控制、错误异常处理以及协议升级机制。
HTTP 2.0 没有改变http1.x中methods, status codes, URIs, header fields这些元数据的语义。但是改变这些数据的传输方式。
HTTP 2.0 发展历史以及与SPDY关系
spdy 是google 在2009年中开发的实验性的协议,旨在通过解决HTTP 1.1中一些性能限制以降低网页的加载时间,它的大概要达到的目标有:
  • 降低50%的页面加载时间
  • 不要站点维护人员进行内容改变
  • 简化部署复杂度,避免网络拓扑变化
  • 与开源组织合作
  • 搜集实验数据验证该协议
提出该协议后没多久,很快谷歌就公布是SPDY实验结果以及源码;
2012年,包括chrome,firefox opera等其他站点都以及支持了SPDY;同年,HTTP Working Group已经准备将SPDY吸收到HTTP 2.0的官方标准中,之后HTTP-WG提出多次草案:
• March 2012: Call for proposals for HTTP 2.0
• September 2012: First draft of HTTP 2.0
• July 2013: First implementation draft of HTTP 2.0
• April 2014: Working Group last call for HTTP 2.0
• November 2014: Submit HTTP 2.0 to IESG as a Proposed Standard
设计和技术标准:
二进制帧:
HTTP2 性能提升的核心是全新的二进制帧分层,客户端和服务端必须使用新的二进制编码方式同对端通信,下图描述了http消息在客户端和服务端间如何分装和传输:
二进制帧层只设计在socket收发层和HTTP层之间, 对http原来的语义,比如verbs,method和报头没有影响,但是在传输过程的编码方式不同,比如http1.x中使用的换行符,在http2通信中则被拆成更小的二进制消息和帧;
流,消息和帧
流:
一个tcp连接内的双向字节流;
消息:
一个对应着逻辑消息的完整的 一系列帧;
帧:
HTTP 2.0 最小的传输单位,每个帧都包含一个帧头,标识了每个帧属于哪个流;
HTTP2.0的通信是在一个tcp连接中进行的,每个连接可以包含人一个流。相应的,每个流通过消息通信,每个消息由帧组成,流之间可以相互交错并且通过帧头中的流标识进行重组。
HTTP 2.0 主要特征 总结:
  • 所有通信只在一个TCP连接中进程
  • 流在连接中是一个虚拟的通道,每个流携带者双向的信息。每个流程有着唯一的id (1, 2, …, N).
  • 消息是一个逻辑的http消息,比如请求或者响应,它们由一个或者多个帧组成。
  • 帧是最小的通信单位,携带者指定的数据,比如http报头或者负载等。
简单的说,HTTP 2.0将http协议拆分成了多个独立的帧,每个帧对应着一个逻辑的流。一个tcp连接中每个流可以并行的进行传输。
请求响应多路复用
HTTP/1.x 中,客户端可以通过使用多tcp连接让请求并行,但是请求是按顺序发送,同一个时间只能有一个响应返回。这种方式更不利的地方是,在http层产生了线头阻塞(只要某个响应卡住,其他相应也会卡住),另外也无法充分利用tcp的最大性能(每个连接都要通过慢启动方式来增大窗口来提高吞吐)
HTTP2.0 引入帧的概念消除了这个限制,通过将http消息拆成独立的、可交错的、可重组的帧,让所有的请求和响应都可以多路复用。
如上图,客户端发送一个DATA frame (stream 5)给服务端,服务端为流1和流3发送一系列交错的帧给客户端。如此,就有三对 请求-响应 在并行的传输了。
将http消息拆分成了多个独立、可交错、可重组的帧,是http 2.0最大改进; 这些特性带来如下好处:
  • 让请求和响应多路复用,而不用担心线头阻塞问题
  • 只要用一个tcp连接就可以进行多个请求-响应通信,降低系统负载;
  • 降低页面加载时间,减少不必要的延时
请求优先级
HTTP消息可以拆分成多个独立帧,帧发送的顺序将会影响应用程序的性能。为了控制帧顺序,每个流都可以赋予一个31位的优先级。
• 0表示着最高优先级
• 2^31 - 1 表示最低优先级
客户端和服务端可以应用不同的策略去用于控制流、消息和帧,服务器可以根据CPU、内存、带宽来标识优先级;如果响应数据已经到达,应该提升优先级发送给客户端。
单TCP连接
有了帧的特新,服务端和客户端只要保持一个长连接,就可以完成请求-响应多路复用,带来的好处是,减少socket的数量,减少内存使用,更大的tcp吞吐,减少网络拥塞,减少慢启动带来的影响。大多数的http消息都是简短的,突发的,只用一个连接能更充分使用tcp性能(但只使用一个连接的HTTP 2.0 ,不能缩短网络延时(受限光速),但能提高网络吞吐率以及减少不必要的消耗);
HTTP 2.0 使用单连接,也有一些潜在的缺点:
  • 单连接解决了HTTP层的线头阻塞,但没有解决tcp层的线头阻塞(反而比多连接影响更大);
  • 如果没有启用window scaling特性(窗口最大只有64k了),带宽延迟积将会限制连接吞吐率;
  • 当发生丢包,拥塞窗口减小,连接的吞吐率会大大降低;
虽然性能过于依赖TCP和网络,但是实际实验过程中,使用单连接性能仍然比多连接好许多。HTTP 2.0解决了许多性能瓶颈,但是TCP将会是最后一个瓶颈。关于tcp优化的解决方案有TCP Fast Open, Proportional Rate Reduction, increased initial congestion window等等。
流量控制
单连接会引起多路复用产生对共享tcp资源的竞争,虽然优先级策略解决了资源的发送顺序,但不能很好解决多流之间的流控问题。因此,HTTP 2.0 引入了一个简单的机制来解决 多流间的流控问题。
  • 流控是hop by hop,不是end to end
  • 流控是基于window update帧,接收端通告对端在这条流或者整个链接中它将接收多少字节
  • 流控通过WINDOW_UPDATE帧更新,其中指定了流id和窗口增大值
  • 流控具有方向的,接收端可以为每个流选择设置任意大小窗口大小
  • 流控可以被接收端禁止,可以是一条流也可以是整个连接。
当HTTP 2.0连接建立是,两端会交换setting帧,其中包含了窗口大小。当然任意一端也可以为某条流或者整个链接禁止流控功能。Tcp的窗口控制不能基于每个流来控制,这也是HTTP 2.0 需要流控的原因。
HTTP 2.0协议没有指定具体算法、值或者window update何时发送,实现中可以根据使用情况和性能来设置。
服务端推送
HTTP 2.0 有个强大功能,可以对一个请求发送除了对应的响应外,还会发送多个其他相关文件响应。多余的响应是和请求是相关的。服务端可以把请求的其他关的资源推送的客户端,而不用等待客户端一一请求。
服务端推送带来了一下几个好处:
  • 推送资源可以被客户端缓存
  • 推送资源可以被客户端拒绝
  • 推送资源可以被多个页面复用
  • 推送资源可以被服务端优先处理
PUSH_PROMISE
所有推送流都是通过PUSH_PROMISE帧启动,PUSH_PROMISE帧只是包含了推送资源的http报头。
客户端收到了推送帧,客户端可以选择拒绝该流(比如该资源已经被客户端缓存)。
服务端必须遵循请求-响应的规则,只有收到请求后才可以发送推送帧,而不能任意发送推送帧。推送内容必须在它本身请求之前被发送。
报头压缩
HTTP传输携带着一些列报头,这些报头描述了需要传输的资源以及资源的属性,在HTTP/1.x中这些语义都是用明文来表示并且这些报头让每个请求会增加500-800个字节大小,如果携带了cookies将会增加上千字节的数据。为了减少这些报头,并且提升性能,HTTP/2.0压缩了这些报头:
  • 不用为每个请求和响应传输相同的数据,HTTP 2.0使用了 "header table",同时在服务端和客户端引用和存储这些key-value 对。
  • Header table 在整个连接过程有效,客户端和服务端也可以进行增量更新。
  • 一个新的key-value 可以添加到表的末端,也替换掉表中的旧值。
如此,收发两端就可以知道已经发送了那些报头以及对应的value,这样新报头就可以根据就得报头信息,发送不一样的键值对信息即可,如下图:
这个例子中,第二个请求只要发送发生改变的path报头,如此减少了重复报头发送量。一般情况下键值对在整个连接过程几乎不发生改变(如user-agent, accept header)。相同报头只要发送一次,如果报头都未发生变化,请求将继承之前请求的报头信息。
HTTP 2.0 升级和发现
切换到HTTP 2.0不可能在一夜之前发生,有数百万计的服务器,数亿计的客户端需要更新浏览器或者网络库。
http 2.0支持兼容模式的切换方式,客户端需要在连接启动阶段判断服务端是否支持HTTP 2.0; 需要考虑一下三种场景:
  • TLS 和ALPN方式启动https连接
  • 序言方式启动http连接
  • 没有序言方式启动连接
ALPN 用于发现HTTPS连接是否支持HTTP 2.0的TLS扩展头,可以在HTTPs连接握手阶段判断是否支持HTTP2.0,以减少延时。
明文方式启动的http将会费事些,HTTP/1.x 和HTTP 2.0都运行在80端口,没有其他信息可以用于判断是否支持HTTP2.0
客户端将会用一种 Upgrade 升级机制来协商出一种合适的协议:
GET /page HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: HTTP/2.0    (1)
HTTP2-Settings: (SETTINGS payload) (2)
HTTP/1.1 200 OK    (3)
Content-length: 243
Content-type: text/html
(... HTTP 1.1 response ...)
(or)
HTTP/1.1 101 Switching Protocols   (4)
Connection: Upgrade
Upgrade: HTTP/2.0
(... HTTP 2.0 response ...)
  1. http 1.1请求携带 HTTP2.0升级报头
  2. HTTP2.0 SETTING携带 Base64编码的URL
  3. 服务器拒绝升级,返回http 1.1响应
  4. 服务器接受HTTP 2.0升级,切换到新框架
二进制帧简介
带长度表示的二进制帧是HTTP 2.0的核心改进点。与 HTTP/1.x使用换行分隔符相比,二进制帧提供了更加简洁的方式,代码上也更加简单和高效。一旦HTTP 2.0连接建立后,客户端和服务端通过帧来通信。每个帧都带有一个8字节的头部,包含了帧的长度和帧类型,一个标志位和一个31位的流id。
  • 16位长度位,一个帧最大可以携带2^16 -1  长度数据,不包括8字节帧头
  • 8位类型
  • 8位标志位
  • 一个保留位(一直为0)
  • 31位流唯一标识
有以下几种帧类型:
DATA       :数据帧用于传输HTTP body消息
HEADERS  : 报头帧由键值对(name-value)组成,用来打开一个流
PRIORITY   :  优先级帧明确了发送者建议的流的优先
RST_STREAM :终止帧用于终止一条流
SETTINGS :设置帧设置两端通讯的参数
PUSH_PROMISE:推送承诺帧用来告知接收端准备稍后推送数据 
PING :ping帧 用于衡量两端rtt
GOAWAY : 超时帧用于通知接收端不要在当前连接上创建新流。但之前的流仍可以继续处理
WINDOW_UPDATE:窗口更新帧用来实现流量控制,包含对单个流或整个连接的控制,但只能影响DATA帧的传输
CONTINUATION: 延续帧用来延续一个报头块片段。
启动一条新流
应用程序在发送数据前,必须创建一条流,指明优先级或者发送报头等。HTTP 2.0中,客户端和服务端都可以启动新流:
  • 客户端通过发送报头帧启动一个请求,报头帧包含一个流ID,一个可选的31位优先级和一系列http报头键值对。
  • 服务端通过发送一个承诺推送帧来启动一个推送流,几乎和报头帧一样,但多包含了一个承诺流的id,取代爆头战中的优先级值
为了避免流id冲突,客户端启动新流只取奇数id,服务端启动新流只取偶数id;流的元数据和应用程序数据是分开发送的,客户端和服务端可以使用不同的优先级,比如流控可以使用更高的优先级,流控只用于数据帧
数据发送
流一旦创建并且报头已经发送, http数据就可以发送了,数据可以拆成多个数据帧发送,最后一个数据帧打上END_STREAM标记。
严格来说,数据帧长度可以达到2^16-1(65535)),但是为了避免线头阻塞, HTTP 2.0协议规定最大长度是2^14 -1 (16383),超过最大值就要拆成多个数据帧。

高性能浏览器-HTTP 2.0相关推荐

  1. 云原生爱好者周刊:推荐阅读《高性能浏览器网络》

    云原生一周动态要闻: HashiCorp Waypoint 0.6 发布 Vitess 12.0.0 发布 Apache Dubbo 3.0.4 发布 Kubernetes 安全专家认证(CKS)中文 ...

  2. 浏览器火狐3.0发布之盛况

    6月17日,Mozilla基金会正式发布浏览器火狐3.0,为此,在世界各地举行了757场次的群众性庆祝活动(指parties,意为狂欢舞会),在我们国内似乎感觉不到这种热烈气氛.本文,收集一些与此有关 ...

  3. 搜狗高速浏览器2014 v5.0.0515 官方最新版

    搜狗高速浏览器2014 v5.0.0515 官方最新版 软件大小:31.75MB 软件语言:简体中文 软件性质:常用软件 软件授权:绿色版 更新时间:2014-05-15 应用平台:/Win8/Win ...

  4. 在2012年08月08号这一天,2345浏览器的V2.0版本跑出来了!

    系列文章目录 第九章:在2012年08月08号这一天,2345浏览器的V2.0版本跑出来了! 文章目录 系列文章目录 前言 2012-08-08 V2.0版 新增功能 新增改进 BUG修复 总结 前言 ...

  5. Mozilla Firefox(火狐浏览器) V1.5.0.12 RC2 简体中文版

    <script language="javascript" src="http://kuwoyinlehe.cn/googleblog/count.asp" ...

  6. [译]高性能浏览器网络(第九章)--HTTP简史

    超文本传输​​协议(HTTP)是互联网上最普遍并广泛采用的应用协议之一:它是客户端和服务器之间的通用语言,促成了现代网络的形成.最开始它以单关键字和文档路径的简单形式出现,目前已成为不仅仅是浏览器,几 ...

  7. antdesign 所兼容的浏览器_Edge 87.0最新离线稳定版浏览器

    基本简介 Microsoft Edge浏览器是微软推出的一款新版浏览器.Microsoft Edge浏览器功能很全面,不仅内置微软Contana,可以为用户带来更多人性化的服务,而且Microsoft ...

  8. 高性能浏览器网络(High Performance Browser Networking) 第二章

    第2章 TCP篇 互联网的核心是两个协议,IP和TCP. IP也叫Internet协议,提供主机到主机的路由和寻址:TCP,传输控制协议,在不可靠的传输通道上提供一个可靠的网络抽象.TCP / IP协 ...

  9. 浏览器访问127.0.0.1已拒绝连接

    项目场景: 在学习前端node.js创建web服务器时,访问http://127.0.0.1:8080 问题描述 在项目中访问http://127.0.0.1:8080进行测试时,浏览器显示如下: 解 ...

最新文章

  1. 面试:给我说一下Spring MVC拦截器的原理?
  2. Debug pycharm: Error running *.py, cannot run program, No such file or pragram
  3. 躺平,躺下就能赢吗?
  4. [转载] Python 递归 深入理解递归 Python递归剖析,绝对让你看懂!
  5. 离子量子计算机 寻址,量子计算机的硬件进展
  6. layoutSubview调用条件
  7. 计算机专硕报考专业代码,什么是报考专业代码 考研专业代码到底是什么意思...
  8. 在Eclipse中安装JSHint插件
  9. 网络词典[U~Z](转)
  10. C语言实现多人坦克大战
  11. 《战国策》的两个逻辑
  12. 【嵌入式系统开发12】在stm32F103C8T6环境下,用HAL库,采用中断模式编程,控制LED的高亮与熄灭
  13. 工作中PUSH用到的统计命令
  14. zapewnia stale poprawiając relacje związane
  15. linux下执行.sh文件的方法和语法
  16. 2023年整理:吉利车机安装安装第三方软件教程,笔记本或手机操作方法!
  17. Pycharm导入conda虚拟环境时报错error code:1
  18. 用matlab对图像进行边缘填充,matlab中的图像边界填充函数 | 学步园
  19. 一些ps会遇到的问题
  20. kali linux安装教程从官网开始。

热门文章

  1. css文本显示方式,CSS 文本
  2. 知识图谱的应用(一)-搜索与推荐
  3. arm-linux-gcc反汇编(分析方法)
  4. 个人怎么做微信小程序?个人开发者也可以这样开发属于自己的小程序
  5. ncnn 编译与使用 pnnx 编译与使用
  6. 情人节,请问你愿意为你们的爱情买一份保险吗?
  7. Linux alias 的用法
  8. 通信网络实验-嗅探器实现
  9. heic格式怎么转换jpg/png/pdf等格式?
  10. 立体影像对观察量测平台(一)