写点什么

HTTP/2 探索第一篇——概念

  • 2019-08-22
  • 本文字数:3490 字

    阅读完需:约 11 分钟

HTTP/2探索第一篇——概念

一、现状

1. 网络性能

现在网络优化的瓶颈是什么?你可能会说,带宽。也许在 2014 年前,决定性能的关键是带宽,但是在今天以及以后,瓶颈都不会是带宽,而是延迟;



从图中可以看出,随着带宽的增长,页面加载时间(PLT Page Load Time)在 1Mbps 到 3Mbps 的区间得到了很大的改善,但是再提高带宽,带来的提升就很小了,属于非线性改善;反观延迟,延迟(这里是指多个 RTT 时间相加的总和)的改善对于页面加载时间是属于线性改善;


HTTP/1.1 TCP 连接是需要三次握手的,同时,多个 TCP 连接也会给服务器带来资源的消耗,在 HTTP/1.1 中,每个请求回复都是一次 TCP 连接(未开启 Keep-Alive 的情况下),并且,同时传输多个资源时,会有队首阻塞的问题,造成网络资源无法有效利用;

2. 安全

对于大多数人来说,下图的情况几乎都有遇到过(电脑或手机里)。万恶的运营商或者网络接入 WiFi 提供商劫持我们的网络,修改网络的内容,给我们带来了很大的困扰;


二、HTTP/2.0

现在,HTTP/2.0 出现了。其实 HTTP/2.0 是支持 Clear Text 版和 Over TLS 版,由于现有支持 HTTP/2.0 的浏览器都是实现的 Over TLS 版,故本文的 HTTP/2.0 都是讲的是 HTTPS 版 HTTP/2.0;

1. Clear Text 版:

客户端向服务端请求(假设此时 scheme 是 HTTP),带有以下头:


Upgrade: h2c


HTTP2-Settings


服务器端返回:


101 状态码,转换协议;


Connection: Upgrade


Upgrade: h2c 或者 200/404

2. HTTP/2.0 Over TLS 版:

客户端向服务器端请求


TLS + ALPN(Application Layer Protocol Negotiation)/NPN


服务器端返回:


TLS 握手 并返回支持的 HTTP 协议;


a. TLS 握手详细过程



b. ALPN 协商过程


参考 TLS 握手过程图,下面是增加 ALPN 协商的具体过程:


客户端添加一个 ProtocolNameList 字段,包含支持的 HTTP 协议到 ClientHello 消息中;


服务器端查看 ProtocolNameList 字段后通过 ServerHello 消息返回 ProtocolName 字段,表明被选定的协议;


通过实现 ALPN,不再需要单独请求一次服务器带上 Upgrade: h2c;


c. False Start


通常情况下,使用 ALPN 会搭配使用 False Start,客户端在完成 TLS 握手前提前发送加密后的应用数据,将两次 RTT TLS 握手减少为一次;不过需要同时支持 ALPN(NPN 已经很少用啦)和前向安全性;


d. HSTS


HTTP Strict Transport Security(简称为 HSTS)是一个安全功能,告诉浏览器只能通过 HTTPS 访问当前资源,禁止 HTTP 方式。


如果用户输入域名www.qq.com,浏览器首先会去请求http://www.qq.com,请求过程是明文非加密的,此时容易被中间人攻击,让网路恶意中间商直接接触到用户信息;而 HSTS 是用户请求时,服务器告诉客户端,下次来请求直接请求 https://,而不要再请求服务器来跳转到 https;


同时,开启 HSTS 后,如果证书认证不通过(比如遭到中间人攻击),浏览器此时强制无法打开该网站;

3. 名词解释

流(Stream):一个 Stream 是包含一条或多条信息,ID 和优先级的双向通道;


消息(Message):消息由帧组成;


帧(Frame):帧有不同的类型,并且是混合的。他们通过 stream id 被重新组装进消息中;

4. 概念解释

a. 二进制帧



HTTP2 的二进制帧是 9 字节(72 bit)


长度:24bit,也就是理论上可以携带 2^24 字节的数据。但通常由于 SETTINGS_MAX_FRAME_SIZE 的设置,不能发送超过 2^14(16384)字节的数据;


类型:8bit,决定了该帧的类型;


DATA : 数据帧


HEADERS : 头部帧


PRIORITY : 设置流的优先级


RST_STREAM : 终止流


SETTINGS : 设置连接参数


PUSH_PROMISE : 服务器推送模拟请求帧


PING : 用来计算 RTT 时间和看是否服务器挂了的 Stream


GOAWAY : 告诉对方停止再向当前连接创建 stream


WINDOW_UPDATE : 流量控制


保留字段:1bit,一般为 0;


Stream ID:31bit,Stream 标识,理论上可以有 2147483648,超过这么多 stream 怎么办呢?


如果是客户端无法再创建新的 stream id,可以直接创建新的 TCP 连接,stream id 被重置;


如果是服务器端无法再创建新的 stream id,服务器将会给客户端发一个 GOAWAY 帧,客户端无法再向该服务器创建 stream,不得不新建 TCP 连接;

5. 新特性

多路复用


头部压缩


资源优先级/依赖关系


流量控制


Server Push(客户端请求一个路径时,服务器推送一个资源给客户端)


a. 多路服用



HTTP/2.0 中,数据在发送端被切分为更小的数据帧用以高效利用链接;


HTTP 1.1 时代,再不开启 Keep-alive 的情况下,每一个请求会占用一个 TCP 连接,而 HTTP/2 将请求和响应消息拆分为各自独立的帧,交错的发送,然后再在接收端重新装配组合。有什么好处呢?


交错的多个请求/响应之间互现不会被阻塞


HTTP/1.1 时代的 Keep-alive 也是保持同一个 TCP 连接,但是由于请求/接收有先后,后面的请求资源会被前面的资源阻塞(没收到响应时不会发新的请求),如下图最左和最右边所示,即便是相比 HTTP 管道,优化也是巨大的:



减少了不必要的延时,改善了网路的利用率(多路复用和资源优先级/依赖关系搭配使用,使得页面重度依赖的资源优先传输);


b. 头部压缩


HTTP/2.0 使用 HPACK 来给头部压缩;


值通过霍夫曼编码;


之前发送的值都被索引起来,之后使用时发现之前发送过该 Header 字段,并且值相同,就会沿用之前的索引来指代那个 Header 值;


Cookies:在 HTTP/2.0 中,Cookie 也将会变为键值对索引起来,而不是一长串字符串;


可以看看我们组 dream 同学的 HTTP/2.0 之特性科普篇——头部压缩,里面有截图部分的数据讲述压缩后的效果;



这里需要讲解一下伪头部字段:


请求:


:authority


:method


:path


:scheme


响应:


:status


所有的伪头部字段都是在所有 Header 的前部;


c. 资源优先级/依赖关系


资源优先级/依赖关系通过 stream 权重和 dependency 来设置;



通过上图可以看到,有一列是叫作 Priority,初始设置是根据 Content-type 来设置优先级的,比如 HTML 是 Highest,CSS 是 High,然后 JS 是 Medium;


Stream 权重值可以设置为 1 到 256 之间;


Stream 可以明确的表示依赖关系;


注意,一定要理解权重和依赖,权重值和依赖关系是作为带宽资源/服务器/客户端处理资源的建议值,但并不能保证他们有特定的传输顺序。让我们来看一张 HTTP/2.0 的依赖关系和权重图:



HTTP/2.0 中的 stream 都默认是依赖于一个根 stream(其实不存在)。权重值是针对同级来计算的,不同级是不用来计算的;


d. 流量控制


与 TCP 的流量控制类似,不过 HTTP/2.0 的流量控制可以到具体帧,而 TCP 是 TCP 连接层面上的。注意:流量控制目前只对 DATA 帧有效!流量控制的算法没有具体要求使用哪一种,但是大概实现的功能是这样的:


两端收发保有一个流量控制(window)窗口;


发送端每发送一个 DATA 帧,就把窗口的大小递减,递减量为这个帧的大小,要是窗口大小小于该帧的大小,那么这个帧就必须被拆分。如果窗口值等于 0,就不能发送任何帧。流量控制的初始默认窗口值大小为 65535 字节(理论上可以设置 2^31-1 字节也就是 2147483647 字节大小的窗口值)。


接收端可以通过发送 WINDOW_UPDATE 帧给发送端,发送端以帧内指定的窗口大小增量加到窗口大小限制上。


e. Server Push


Server Push 的资源同样需要遵守同源策略,通过:authority 来判断;



如 Demo 里所示,如果在服务器端设置当请求 Path/examples/dashboard 时就推送/examples/dashboard/d3.js,现在我们来看抓包:



说明:


当客户端请求服务器时(此时的请求路径已经设置好推送),服务器发回一个 PUSH_PROMISE 和两个 HEADERS Frame,从 Stream Identifier 可以看出,第一个 HEADERS 的 Stream ID 是 1,也就是复用请求的 Stream 来返回(这是 HTML 文件的返回响应 Header)。第二个 HEADERS 就是推送文件的响应 Header。


根据定义,由客户端初始化发起的 Stream 的标识符是奇数,由服务器端初始化发起的 Stream 是偶数,图中可以体现;


那么 Stream 1 和 Stream 2 的顺序如何保证呢?说明文档里有这样一句话:


Pushed streams initially depend on their associated stream.


也就是说,服务器将要推送的资源依赖于触发推送的请求,根据 Stream 依赖的功能,只有被依赖的 stream 加载完后才会去加载接下来的 stream;


Server Push 有什么好处呢:


推送的资源可以被客户端缓存;


推送的资源可以被不同的页面复用;


推送资源也是支持多路复用的;


推送资源可以被客户端拒绝掉(客户端接收到 PUSH_PROMISE 后,可以选择发送 RST_PROMISE 来拒绝接收,告诉服务器端不要再发送了,当然,此时可能已经有部分内容已经发送过来了);


同时,Server Push 配合流量控制,可以实现很多很神奇的功能,这里卖个关子,然后会在下一篇讲解 :)


本文转载自公众号小时光茶舍(ID:gh_7322a0f167b5)。


原文链接:


https://mp.weixin.qq.com/s/Y1x0GUkfRbWEz6YsJrMTAQ


2019-08-22 19:063491

评论

发布
暂无评论
发现更多内容

人工智能发展到什么阶段了,产生“自主情感”可能吗?

燕陈华

人工智能 深度学习 卷积神经网络

湖仓一体电商项目背景与架构介绍及基础环境准备

Lansonli

大数据项目 7月月更 签约计划第三季 湖仓一体电商项目

延迟队列DelayQueue性能测试

FunTester

500强企业如何提升研发效能?来看看行业专家怎么说!

万事ONES

基于 Spring Cloud 的微服务架构分析

程序知音

Java 程序员 微服务 SpringCloud 后端技术

Flink消费kafka消息实战

程序员欣宸

Java flink 7月月更

单机高并发模型设计

C++后台开发

reactor 高并发 线程池 C/C++后台开发 C/C++开发

企业运维安全就用行云管家堡垒机!

行云管家

网络安全 运维安全 运维堡垒机 企业数据安全

技术实践干货 | 从工作流到工作流

观远数据

工作流 workflow

x-sheet 开发教程:初始化配置自定义布局

OpenHacker

Excel x-sheet sheet spreadsheet

常见分布式理论(CAP、BASE)和一致性协议(Gosssip、Raft)

程序员啊叶

Java 编程 程序员 架构 java面试

语音直播系统——提升云存储安全性的必要手段

开源直播系统源码

直播系统源码 语音直播系统 语音直播系统连麦

「行话」| 汽车软件如何高效交付?我们总结了这三个关键点

极狐GitLab

git DevOps gitlab DevSecOps 汽车

细数国产接口协作平台的六把武器!

Liam

开发 Postman API 接口开发 前后端协作

美团到餐“祖传数仓”标准化治理笔记

老猎人

2022年中国网络视频市场年度综合分析

易观分析

数据分析 数字媒体 市场

别再用 System.currentTimeMillis 统计耗时了,太 Low,试试 Spring Boot 源码在用的 StopWatch吧,够优雅!

沉默王二

Java

云管平台中租户以及多租户概念简单说明

行云管家

云计算 云管平台

C语言怎么学?这篇文章给你完整答案

图灵教育

C语言

Gartner 权威预测未来4年网络安全的8大发展趋势

SEAL安全

安全 趋势 预测

兆骑科创创业大赛策划承办机构,双创平台,项目落地对接

兆骑科创凤阁

纯css实现:文字可换行的下划线、波浪线等效果

南极一块修炼千年的大冰块

7月月更

Mall微服务版本全面升级!支持最新版SpringCloud

程序知音

Java spring 编程 程序员 后端技术

详解分布式系统的幂等

焱融科技

分布式系统 存储 文件存储 幂等性

写好技术原创文章的一点建议

Qunar技术沙龙

技术文章

选择体育场馆的LED显示屏时应该注重哪些方面

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家

阿里经典30道Java面试题,看完记得收藏保存

程序员啊叶

Java 编程 程序员 架构 java面试

万字详解 Google Play 上架应用标准包格式 AAB

融云 RongCloud

Google 安卓

如何开发一款基于 Vite+Vue3 的在线Excel表格系统(上)

葡萄城技术团队

前端 vite vue3.0

什么是Tor?Tor浏览器更新有什么用?

郑州埃文科技

TCP/IP tor 洋葱路由

HTTP/2探索第一篇——概念_安全_张浩然_InfoQ精选文章