迟来的HTTP2简明教程

The standardization effort was supported by Chrome, Opera, Firefox,[9] Internet Explorer 11, Safari, Amazon Silk, and Edge browsers.[10] Most major browsers had added HTTP/2 support by the end of 2015.[11] According to W3Techs, as of November 2017, 20.5% of the top 10 million websites supported HTTP/2.

这是一段来自维基百科的关于HTTP2的说明,截止2015年底,主流浏览器都已经对HTTP2做了支持,根据2017年11月的W3Techs报告说明,全球有1/5的大型网站都已经使用了HTTP2了。作为码农的你已经可以预料HTTP2的时代即将到来,对于HTTP2的技术细节你都准备好了么?

HTTP2的设计要点

  1. 高度兼容HTTP1.1
  2. 减少客户端服务器的交互延迟
    1. Header压缩
    2. Server Push
    3. Pipelining & Mulplexing

我们平常听到的GZIP压缩仅仅是针对HTTP请求的Body部分进行的,这只能算是半压缩。对于很多API服务来说,返回的内容体其实并不大,这个时候请求头就占据了大部分流量。HTTP2将魔爪伸到了HTTP头部,这回是彻底的对整个请求都进行压缩了。

HTTP2的头压缩原理完全不同于HTTP1.1,它将常用的HEADER键值对映射到一个静态表里面的索引值,于是很多头部的键值对使用一个位置索引来表示就可以了。这样便大大节省了头部消息的长度。对于那些不常用的自定义的头部会使用一个动态表来维护,具体原理有一定复杂度,这里就不再啰嗦了。

Server Push不同于Websocket,Server Push一般是指服务器主动向客户端推送数据,这是一种单向的主动推送,而WebSocket是双向的,这两种技术不是竞争关系。Server Push可以用在服务器主动向客户端推送静态资源,比如浏览器请求index.html时,服务器除了返回网页内容外,还会将index.html页面里面的各种css和js一起推送到浏览器缓存起来,当浏览器分析了网页内容发现静态资源时,不需要再去服务器请求一次,它只需要从缓存里直接拿就可以了。不过现代的网站的静态资源大多都是CDN架构的,静态资源都在第三方服务器,Server Push在这方面作用并不大。Server Push还可以用在推送通知消息,比如谁关注了你,谁给你点了赞等,这个可以替代古老的Comet技术和近几年Google推广的SPDY协议,它需要服务器维持当前的TCP通道不关闭,需要持续占用服务器资源。

Pipeline是指后一个HTTP请求无需等待前一个HTTP请求返回结果就可以提前发起。HTTP1.1也有Pipeline支持,但是有所不足,并行的还不够彻底。它可以提前发起请求,但是却限定了返回结果必须和收到请求的顺序保持一致而不能乱序。如果第一个请求服务器处理慢了,那么后续的返回结果客户端无法立即收到,而必须等到第一个结果全部返回了才行。HTTP2则解决了这个问题,它支持乱序返回,甚至不同请求的返回结果的分块【HTTP Chunk】也可以交叉返回而不会混乱,这种技术称之为Multiplexing【多路复用】。

HTTP2底层协议

HTTP2协议是二进制协议,不同于HTTP1.1的文本协议。文本协议是以特殊的符号结尾【换行回车符】来分割消息的,而二进制协议是通过字节长度来分割消息。二进制协议虽然直观性不如文本协议,但是在实现的时候要简单直接一些。

HTTP2为支持多路复用,在同一条TCP通道上支持发送多个资源/请求,将每条资源/请求定义为一个Stream【流】,同一个TCP通道可以传输多个Stream。同时为了支持多个资源的并行交错发送,将Stream再次分割为多个Frame【帧】,帧与帧之间可以交错发送。接收端通过流ID将这些帧组装起来,通一个流ID的帧属于同一个资源/请求。因为TCP协议已经可以保证消息包是有序的,所以接收端不必担心乱序问题。

HTTP2的帧格式非常简单,就是长度+类型+标志位+流ID+PayLoad,长度就是PayLoad的字节数,类型为一个字节,标志位为1个字节,流ID为4个字节,剩下的长度就是PayLoad。不同类型的帧PayLoad不一样,标志位也不一样。

HTTP2标准里定义了10种类型的帧。

  1. HEADERS帧 头信息,对应于HTTP HEADER
  2. DATA帧 对应于HTTP Response Body
  3. PRIORITY帧 用于调整流的优先级
  4. RST_STREAM帧 流终止帧,用于中断资源的传输
  5. SETTINGS帧 用户客户服务器交流连接配置信息
  6. PUSH_PROMISE帧 服务器向客户端主动推送资源
  7. GOAWAY帧 通知对方断开连接
  8. PING帧 心跳帧,检测往返时间和连接可用性
  9. WINDOW_UPDATE帧 调整帧大小
  10. CONTINUATION帧 HEADERS太大时的续帧

HTTP2标准定义了3个标志位

  1. END_STREAM 流结束标志,表示当前帧是流的最后一个帧
  2. END_HEADERS 头结束表示,表示当前帧是头信息的最后一个帧
  3. PADDED 填充标志,在数据Payload里填充无用信息,用于干扰信道监听

对于一个普通的GET请求来说,它使用一个HEADERS帧就可以表达。HEADERS帧会设置标志位END_STREAM和END_HEADERS表示当前帧是一个完整的HEADERS帧,也是一个完整的HTTP请求流。

对于一个普通的GET请求响应来说,它使用一个HEADERS帧和多个DATA帧就可以表达。HEADERS帧设置END_HEADERS表示当前帧是一个完整的HEADERS帧,后面的DATA帧表示返回的数据,对应Response Body。在HTTP1.1里面返回的Body长度较大,就需要分Chunk进行传输。HTTP2是通过分成多个DATA帧来进行的,最后一个DATA帧有一个END_STREAM标记表示Body的结束。

如果HEADERS太大无法用一个HEADERS帧表达,可以后面跟多个CONTINUATION帧,最后一个帧附加END_HEADERS标志即可。

在服务器主动向客户端推送资源时,同一个资源流里不使用HEADERS帧,取而代之的是PUSH_PROMISE帧,表示服务器承诺客户端即将推送指定资源数据,用于区别一个常规的HTTP GET资源请求。

如果一个TCP连接正在被用于客户端从服务器下载一个大型文件,那么客户端取消发送这个文件的办法只有一个,就是关闭连接。HTTP2则可以在不关闭连接的情况下终止发送文件,客户端向服务器发送一个RST_STREAM帧通知服务器停止相应的资源流即可。这个连接还可以继续服务其它的请求。

HTTP2服务器接收到一个客户端的连接时,第一个要干的事就是和客户端交换SETTINGS帧信息,告知对方一些交互元信息的设置,例如是否开启服务器推送,并行的最大流数量,单帧最大长度等。

在客户端观看视频流时,如果服务器发送的太慢会影响观看体验,如果发的太快,会对客户端的浏览器缓存造成压力。客户端可以使用WINDOW_UPDATE帧通知服务器调整帧窗口大小进而控制服务区发送的数据速率。

原文发布于微信公众号 - 码洞(codehole)

原文发表时间:2018-02-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Seebug漏洞平台

CVE-2017-16943 Exim UAF漏洞分析--后续

作者:Hcamael@知道创宇404实验室 上一篇分析出来后,经过@orange的提点,得知了meh公布的PoC是需要特殊配置才能触发,所以我上一篇分析文章最后...

3266
来自专栏Java职业技术分享

分布式 | Dubbo 架构设计详解

Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度...

2680
来自专栏java思维导图

Java中高级面试题部分答案解析(4)

这里选了几道高频面试题以及一些解答。不一定全部正确,有一些是没有固定答案的,如果发现有错误的欢迎纠正,如果有更好的回答,热烈欢迎留言探讨。

1353
来自专栏JAVA高级架构

大型网站系统与 Java 中间件实践

第一章 分布式系统介绍 分布式系统的定义:组件分布在网络计算机上,组件间仅仅通过消息传递来通信并协调行动。 分布式系统的意义: 升级单机处理能力的性价比越来越...

4197
来自专栏腾讯大数据的专栏

网卡收包流程

0.前言 为提升信鸽基础服务质量,笔者就网络收包全流程进行了内容整理。 网络编程中我们接触得比较多的是socket api和epoll模型,对于系统内核和网卡驱...

2.2K14
来自专栏代码世界

Python中的logger和handler到底是个什么鬼

最近的任务经常涉及到日志的记录,特意去又学了一遍logging的记录方法。跟java一样,python的日志记录也是比较繁琐的一件事,在写一条记录之前,要写好多...

3349
来自专栏数据之美

Zookeeper 原理与实践

1、Zookeeper 的由来 在Hadoop生态系统中,许多项目的Logo都采用了动物,比如 Hadoop 和 Hive 采用了大象的形象,HBase 采用了...

8368
来自专栏小小挖掘机

整理一些计算机基础知识!

为了使不同计算机厂家生产的计算机能够相互通信,以便在更大的范围内建立计算机网络,国际标准化组织(ISO)在1978年提出了“开放系统互联参考模型”,即著名的OS...

1133
来自专栏Python中文社区

Python爬虫抓取收集考试大纲

專 欄 ❈ Garfield_Liang,Python中文社区专栏作者。 博客地址:http://www.jianshu.com/u/cac1d39abfa9 ...

23810
来自专栏芋道源码1024

Java中高级面试题(4)

这里选了几道高频面试题以及一些解答。不一定全部正确,有一些是没有固定答案的,如果发现有错误的欢迎纠正,如果有更好的回答,热烈欢迎留言探讨。

1920

扫码关注云+社区

领取腾讯云代金券