HTTP/2协议–特性扫盲篇

随着web技术的飞速发展,1999年制定的HTTP 1.1已经无法满足大家对性能的要求,Google推出协议SPDY,旨在解决HTTP 1.1中广为人知的性能问题。SPDY得到了Chrome、Firefox和Opera的支持,很多大型网站(如谷歌、Twitter、Facebook、淘宝)都对兼容客户端使用SPDY。SPDY在被行业采用并证明能够大幅提升性能之后,已经具备了成为一个标准的条件。

HTTP工作组采用了SPDY v2草案作为制定HTTP 2.0标准的起点,2014年12月将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。HTTP/2标准于2015年5月以RFC 7540正式发表。至此,SPDY完成了历史的使命,即将退出历史的舞台,HTTP/2粉墨登场。

在HTTP的语义、HTTP方法、状态码、URI和首部字段等核心概念不变的情况下,HTTP/2实现了性能优化,HTTP/2具体有哪些变化呢?下面一一解答 O(∩_∩)O~

二进制分帧(Binary Framing)

HTTP1.x以换行符作为纯文本的分隔符。

HTTP/2将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,我们先了解几个概念:

  • 帧(Frame):HTTP/2通信的最小单位,每个帧包含帧首部,至少也会标识出当前帧所属的流。
  • 消息(Message):由一个或多个帧组合而成,例如请求和响应。
  • 连接(Connection):与 HTTP/1 相同,都是指对应的 TCP 连接;
  • 流(Stream):已建立的连接上的双向字节流。

在HTTP/2中,数据流以消息的形式发送,而消息由一个或多个帧组成,帧可以在数据流上乱序发送,然后再根据每个帧首部的流标识符重新组装。二进制分帧是HTTP/2的基石,其他优化都是在这一基础上来实现的。

多路复用(Request and Response Multiplexing)

HTTP1.x中,如果想并发多个请求,必须使用多个TCP链接,且浏览器为了控制资源,还会对单个域名有6-8的个数限制,如下图,红色圈出来的请求就因域名链接数已超过限制,而被挂起等待了一段时间:

针对这一问题,我们做了很多优化,例如合并请求、图片精灵、散列域名等

在 HTTP/2 中,有了二进制分帧之后,HTTP 2.0不再依赖TCP链接去实现多流并行了,在HTTP/2:

  • 同域名下所有通信都在单个连接上完成。
  • 单个连接可以承载任意数量的双向数据流。
  • 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。

这一特性,性能会有极大的提升,因为:

  • 同个域名只需要占用一个TCP连接,消除了因多个TCP连接而带来的延时和内存消耗。
  • 单个连接上可以并行交错的请求和响应,之间互不干扰。

流优先级( Stream priority)

在HTTP/2中,每个请求都可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。

服务器推送(Server push)

Server push是HTTP/2中一个很强大的功能:

  • 服务器除了响应客户端的请求外,还可以向客户端额外推送资源。
  • 服务器推送的资源有自己独立的URL, 可以被浏览器缓存,可以达到多页面共享。
  • 资源推送遵守同源策略,服务器不可随便推送第三方资源给客户端。
  • 客户端可以拒绝推送过来的资源。

有了这一特性,我们可以做什么?

  • 应用可以通过额外的http头部,列出需要服务器推送哪些资源。
  • 服务器可以解析请求的html,推测出客户端接下来需要请求的资源,然后提前向客户端推送。
  • 等等

头部压缩(Header Compression)

HTTP每一次通信都会携带一组头部,用于描述这次通信的的资源、浏览器属性、cookie等,例如

在HTTP 1.x中,这些信息都是以纯文本协议发送的,给每个请求增加了不小的负荷。

为了减少这块的开销并提升性能, HTTP/2会压缩这些首部:

  • HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;
  • 首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新;
  • 每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值。

例如:下图中的两个请求, 请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。

我们来看一个实际的例子,下面是用WireShark抓取的访问google首页的包:

上图是是访问https://www.google.com/抓到的第一个请求的头部,可以看到头部的内容,总共占用了437 bytes,我们选中头部的cookie,可以看到cookie总共占用了118 bytes。接下来我们看看第二个请求的头部:


从上图可以看到,得益于头部压缩,第二个请求中cookie只占用了1个字节,我们来看看变化了的Accept字段:

由于Accept字段与请求一中的内容不同,需要发送给服务器,所以占用了29 bytes。

应用层协商协议(APLN:Aplication Layer Protocol Negotiation)

客户端、服务器都需要升级才能支持HTTP 2.0,升级过程中就存在HTTP1.1、HTTP 2.0并存的情况,然而他们都使用的80端口,那么如何来选择使用什么协议通信呢?

APLN就是为了解决这个问题的,通过协商来选择通信的协议:

  1. 客户端发起请求,如果支持HTTP/2,则带upgrade头部:
    GET /page HTTP/1.1
    Host: server.example.com
    Connection: Upgrade, HTTP2-Settings
    Upgrade: HTTP/2.0
    HTTP2-Settings: (SETTINGS payload)
  2. 服务器不支持,则拒绝升级,通过HTTP1.1返回响应
    HTTP/1.1 200 OK
    Content-length: 243
    Content-type: text/html
    (... HTTP 1.1 response ...)
  3. 服务器支持,则接受升级,切换到新分帧,使用HTTP/2通信。
    HTTP/1.1 101 Switching Protocols
    Connection: Upgrade
    Upgrade: HTTP/2.0
    (... HTTP 2.0 response ...)

使用协议协商,无论是哪一种情况,都不需要额外的往返,如果客户端通过记录或者其他方式,知道服务器支持HTTP/2,则直接使用HTTP/2通信,无需再协议协商。

Ending

最后,简而概之,HTTP/2的通过支持请求与响应的多路复用来减少延迟,通过压缩HTTP首部字段将协议开销降至最低,同时增加对请求优先级和服务器端推送的支持。

HTTP/2性能得到了极大的提升,我们在HTTP 1.1时代做的有些优化反而成了鸡肋,在升级过程中,如何让HTTP/2 和 HTTP 1.1的用户都能得到最优的性能,这是对于我们的另外一大挑战。

参考资料:

  1. 《High Performance Browser Networking》 –Ilya Grigorik;
  2. 《Web性能权威指南》-李松峰翻译;
  3. Jerry Qu blog 中的HTTP/2专题;
  4. HTTP/2 rfc 7540;
  5. HTTP/2 协议 中英对照版 –百度 FEX
  6. 维基百科:HTTP/2
 

HTTP/2协议–特性扫盲篇的更多相关文章

  1. Httpd服务入门知识-http协议版本,工作机制及http服务器应用扫盲篇

    Httpd服务入门知识-http协议版本,工作机制及http服务器应用扫盲篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Internet与中国 Internet最早来源于美 ...

  2. 分布式协调服务Zookeeper扫盲篇

    分布式协调服务Zookeeper扫盲篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 身为运维工程师对kubernetes(k8s)可能比较熟,那么etcd(go语言实现)分布式协 ...

  3. 高级Linux运维工程师必备技能(扫盲篇)

    高级Linux运维工程师必备技能(扫盲篇) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在了解文件系统之前,我们要学习一下磁盘存储数据的方式,大家都知道文件从内存若要持久化存储的 ...

  4. C语言扫盲篇

    C语言扫盲篇 作者:尹正杰 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接. 一.什么是C语言 C 语言是一种通用的高级语言,最初是由 ...

  5. MySQL数据库扫盲篇

    MySQL数据库扫盲篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.MySQL概述 1>.什么是MySQL MySQL是瑞典的MySQL AB公司开发的一个可用于各 ...

  6. 转摘 MySQL扫盲篇

    一下文章摘自:http://www.jellythink.com/archives/636 MySQL扫盲篇 2014-09-15 分类:MySQL / 数据库 阅读(1412) 评论(1)  为什么 ...

  7. 01--Qt扫盲篇

    Qt扫盲篇 1.What is Qt 一个跨平台应用程序和UI开发框架,主要偏向于UI框架方面,由诺基亚公司开发维护. 使用 Qt 只需一次性开发应用程序,无须重新编写源代码,便可跨不同桌面和嵌入式操 ...

  8. C# 9 新特性 —— 补充篇

    C# 9 新特性 -- 补充篇 Intro 前面我们分别介绍了一些 C# 9 中的新特性,还有一些我觉得需要了解一下的新特性,写一篇作为补充. Top-Level Statements 在以往的代码里 ...

  9. C#扫盲篇(三):Action和Func委托--实话实说

    一.基础定义 老王想找老张的老婆出去耍,但是一看,老张还在厨房煮饭.于是老王就对老张隔壁的淑芬说:"等下老张吃完饭出去喝茶,你就把前门晒的苞谷收了,老张从左门出,你就收右边的苞谷,我就知道从 ...

随机推荐

  1. JS生成URL二维码

    需求:项目中需要在UI界面有一个二维码,扫码后可以跳转到二维码包含的URL. 解决方案:在前端用js生成一个包含URL等信息的二维码. 实现: 方案一. <!DOCTYPE HTML PUBLI ...

  2. vue项目部署到服务器

    1.配置config目录下index.js index: path.resolve(__dirname, '../dist/index.html'), assetsRoot: path.resolve ...

  3. 1 - IO

    IO流第二天 今日内容 字节流 字符流 字节流 在前面的学习过程中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现在我们就要开始给文件中写数据,或者读取文件中的数据 字节输出流Outp ...

  4. error: failed to push some refs to 'https://gitee.com/xxx/xxx'

    一开始以为是本地版本和线上的差异 果断先直接pull  之后 还是不对,哎 不瞎搞了  搜... 获得消息: git pull --rebase origin master 原来如此:是缺失了文件

  5. Nginx服务器中配置非80端口的端口转发方法详解

    这篇文章主要介绍了Nginx服务器中配置非80端口的端口转发方法详解,文中使用到了Nginx中的proxy_pass配置项,需要的朋友可以参考下 nginx可以很方便的配置成反向代理服务器: 1 2 ...

  6. 第49章:MongoDB-数据导入导出

    ①导出工具mongoexport Mongodb中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件.可以通过参数指定导出的数据项,也可以根据指定的条件导出 ...

  7. SSRF

    SSRF 关于SSRF SSRF(Server-Side Request Forgery:服务器端请求伪造),攻击者通过伪造服务器端发起的请求,获取客户端所不能得到的数据.一般情况下,SSRF攻击的目 ...

  8. JavaScriptDOM

    DOM简介 1.HTML DOM:网页被加载时,浏览器会创建文档对象模型 2.DOM操作HTML:改变HTML的元素.属性.CSS样式.对所有事件作出反应 DOM操作HTML 1.改变HTML输出流 ...

  9. linux_批量关闭进程

    以下环境是 fedora24 linux 系统中的情况: 仿真中遇到意外弹出上百个图片,无法一下全部关闭. 可以使用: ps -ef|grep LOCAL=NO|grep -v grep|cut -c ...

  10. HARD FAULT

    程序陷在while(1)里面 解决办法 定点到发生死循环的位置 打开stack windows逐层查找发生死循环之前运行过的函数 导致原因 1 内存溢出或者访问越界,通常为数组或结构体访问越界.这个需 ...