百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

HTTP 2.0 原理(http基本原理)

csdh11 2025-03-23 18:35 16 浏览

架构师-网络文章汇总

HTTP 2.0是在SPDY(An experimental protocol for a faster web, The Chromium Projects)基础上形成的下一代互联网通信协议。HTTP/2 的目的是通过支持请求与响应的多路复用来较少延迟,通过压缩HTTPS首部字段将协议开销降低,同时增加请求优先级和服务器端推送的支持。

本文目的是学习HTTP 2.0的原理并研究其通信的详细细节。

1. 二进制分帧层

二进制分帧层,是HTTP 2.0性能增强的核心。
HTTP 1.x在应用层以纯文本的形式进行通信,而HTTP 2.0将所有的传输信息分割为更小的消息和帧,并对它们采用二进制格式编码。这样,客户端和服务端都需要引入新的二进制编码和解码的机制。

如下图所示,HTTP 2.0并没有改变HTTP 1.x的语义,只是在应用层使用二进制分帧方式传输。


因此,也引入了新的通信单位:

1.1 帧(frame)

HTTP 2.0通信的最小单位,包括帧首部、流标识符、优先值和帧净荷等。

其中,帧类型又可以分为:

  • DATA:用于传输HTTP消息体;
  • HEADERS:用于传输首部字段;
  • SETTINGS:用于约定客户端和服务端的配置数据。比如设置初识的双向流量控制窗口大小;
  • WINDOW_UPDATE:用于调整个别流或个别连接的流量
  • PRIORITY: 用于指定或重新指定引用资源的优先级。
  • RST_STREAM: 用于通知流的非正常终止。
  • PUSH_ PROMISE: 服务端推送许可。
  • PING: 用于计算往返时间,执行“ 活性” 检活。
  • GOAWAY: 用于通知对端停止在当前连接中创建流。

标志位用于不同的帧类型定义特定的消息标志。比如DATA帧就可以使用End Stream: true表示该条消息通信完毕。流标识位表示帧所属的流ID。优先值用于HEADERS帧,表示请求优先级。R表示保留位。
下面是Wireshark抓包的一个DATA帧:

1.2 消息(message)

消息是指逻辑上的HTTP消息(请求/响应)。一系列数据帧组成了一个完整的消息。比如一系列DATA帧和一个HEADERS帧组成了请求消息。

1.3 流(stream)

流是连接中的一个虚拟信道,可以承载双向消息传输。每个流有唯一整数标识符。为了防止两端流ID冲突,客户端发起的流具有奇数ID,服务器端发起的流具有偶数ID。
所有HTTP 2. 0 通信都在一个TCP连接上完成, 这个连接可以承载任意数量的双向数据流Stream。 相应地, 每个数据流以 消息的形式发送, 而消息由一 或多个帧组成,
这些帧可以乱序发送, 然后根据每个帧首部的流标识符重新组装。


二进制分帧层保留了HTTP的语义不受影响,包括首部、方法等,在应用层来看,和HTTP 1.x没有差别。同时,所有同主机的通信能够
在一个TCP连接上完成。

2. 多路复用共享连接

基于二进制分帧层,HTTP 2.0可以在共享TCP连接的基础上,同时发送请求和响应。HTTP消息被分解为独立的帧,而不破坏消息本身的语义,交错发送出去,最后在另一端根据流ID和首部将它们重新组合起来。
我们来对比下HTTP 1.x和HTTP 2.0,假设不考虑1.x的pipeline机制,双方四层都是一个TCP连接。客户端向服务度发起三个图片请求/image1.jpg,/image2.jpg,/image3.jpg。
HTTP 1.x发起请求是串行的,image1返回后才能再发起image2,image2返回后才能再发起image3。


HTTP 2.0建立一条TCP连接后,并行传输着3个数据流,客户端向服务端乱序发送stream1~3的一系列的DATA帧,与此同时,服务端已经在返回stream 1的DATA帧


性能对比,高下立见。HTTP 2.0成功解决了HTTP 1.x的
首阻塞问题(TCP层的阻塞仍无法解决),同时,也不需要通过pipeline机制多条TCP连接来实现并行请求与响应。减少了TCP连接数对服务器性能也有很大的提升。

3. 请求优先级

流可以带有一个31bit的优先级:

  • 0:表示最高优先级
  • 231-1:表示最低优先级

客户端明确指定优先级,服务端可以根据这个优先级作为依据交互数据,比如客户端优先级设置为.css>.js>.jpg(具体可参见《高性能网站建设指南》), 服务端按优先级返回结果有利于高效利用底层连接,提高用户体验。
然而,也不能过分迷信请求优先级,仍然要注意以下问题:

  • 服务端是否支持请求优先级
  • 会否引起队首阻塞问题,比如高优先级的慢响应请求会阻塞其他资源的交互。

4. 服务端推送

HTTP 2.0增加了服务端推送功能,服务端可以根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。如下图所示,客户端请求stream 1,/page.html。服务端在返回stream 1消息的同时推送了stream 2(/script.js)和stream 4(/style.css)。


PUSH_PROMISE帧是服务端向客户端有意推送资源的信号。

  • 如果客户端不需要服务端Push,可在SETTINGS帧中设定服务端流的值为0,禁用此功能
  • PUSH_PROMISE帧中只包含预推送资源的首部。如果客户端对PUSH_PROMISE帧没有意见,服务端在PUSH_PROMISE帧后发送响应的DATA帧开始推送资源。如果客户端已经缓存该资源,不需要再推送,可以选择拒绝PUSH_PROMISE帧。
  • PUSH_PROMISE必须遵循请求-响应原则,只能借着对请求的响应推送资源。
    目前,Apache的mod_http2能够开启 H2Push on服务端推送Push。Nginx的ngx_http_v2_module还不支持服务端Push。
Apache mod_headers example

    Header add Link "</css/site.css>;rel=preload"
    Header add Link "</images/logo.jpg>;rel=preload"
12345

5. 首部压缩

HTTP 1.x每一次通信(请求/响应)都会携带首部信息用于描述资源属性。HTTP 2.0在客户端和服务端之间使用“首部表”来跟踪和存储之前发送的键-值对。首部表在连接过程中始终存在,新增的键-值对会更新到表尾,因此,不需要每次通信都需要再携带首部。


另外,HTTP 2.0使用了首部压缩技术,压缩算法使用HPACK。可让报头更紧凑,更快速传输,有利于移动网络环境。
需要注意的是,HTTP 2.0关注的是首部压缩,而我们常用的gzip等是报文内容(body)的压缩。二者不仅不冲突,且能够一起达到更好的压缩效果。

6. 一个完整的HTTP 2.0通信过程

考虑一个问题,客户端如何知道服务端是否支持HTTP 2.0?是否支持对二进制分帧层的编码和解码?所以,在两端使用HTTP 2.0通信之前,必然存在协议协商的过程。

6.1 基于ALPN的协商过程

支持HTTP 2.0的浏览器可以在TLS会话层自发完成和服务端的协议协商以确定是否使用HTTP 2.0通信。其原理是TLS 1.2中引入了扩展字段,以允许协议的扩展,其中ALPN协议(Application Layer Protocol Negotiation, 应用层协议协商, 前身是NPN)用于客户端和服务端的协议协商过程。
服务端使用ALPN,监听443端口默认提高HTTP 1.1,并允许协商其他协议,比如SPDY和HTTP 2.0。
比如,客户端在TLS握手Client Hello阶段表明自身支持HTTP 2.0


服务端收到后,响应Server Hello,表示自己也支持HTTP 2.0。双方开始HTTP 2.0通信。

6.2 基于HTTP的协商过程

然而,HTTP 2.0一定是HTTPS(TLS 1.2)的特权吗?
当然不是,客户端使用HTTP也可以开启HTTP 2.0通信。只不过因为HTTP 1. 0和HTTP 2. 0都使用同一个 端口(80), 又没有服务器是否支持HTTP 2. 0的其他任何 信息,此时 客户端只能使用HTTP Upgrade机制(OkHttp, nghttp2等组件均可实现,也可以自己编码完成)通过协调确定适当的协议:

HTTP Upgrade request
GET / HTTP/1.1
host: nghttp2.org
connection: Upgrade, HTTP2-Settings
upgrade: h2c        /*发起带有HTTP2.0 Upgrade头部的请求*/       
http2-settings: AAMAAABkAAQAAP__   /*客户端SETTINGS净荷*/
user-agent: nghttp2/1.9.0-DEV

HTTP Upgrade response    
HTTP/1.1 101 Switching Protocols   /*服务端同意升级到HTTP 2.0*/
Connection: Upgrade
Upgrade: h2c

HTTP Upgrade success               /*协商完成*/1234567891011121314

6.3 完整通信过程

TCP连接建立:


TLS握手和HTTP 2.0通信过程:


另外,在chrome中通过
chrome://net-internals/#http2命令也能捕获HTTP 2.0通信过程:

42072: HTTP2_SESSION
textlink.simba.taobao.com:443 (PROXY 10.19.110.55:8080)
Start Time: 2017-04-05 11:39:11.459

t=370225 [st=    0] +HTTP2_SESSION  [dt=32475+]
                     --> host = "textlink.simba.taobao.com:443"
                     --> proxy = "PROXY 10.19.110.55:8080"
t=370225 [st=    0]    HTTP2_SESSION_INITIALIZED
                       --> protocol = "h2"
                       --> source_dependency = 42027 (PROXY_CLIENT_SOCKET_WRAPPER)
t=370225 [st=    0]    HTTP2_SESSION_SEND_SETTINGS
                       --> settings = ["[id:3 flags:0 value:1000]","[id:4 flags:0 value:6291456]","[id:1 flags:0 value:65536]"]
t=370225 [st=    0]    HTTP2_STREAM_UPDATE_RECV_WINDOW
                       --> delta = 15663105
                       --> window_size = 15728640
t=370225 [st=    0]    HTTP2_SESSION_SENT_WINDOW_UPDATE_FRAME
                       --> delta = 15663105
                       --> stream_id = 0
t=370225 [st=    0]    HTTP2_SESSION_SEND_HEADERS
                       --> exclusive = true
                       --> fin = true
                       --> has_priority = true
                       --> :method: GET
                           :authority: textlink.simba.taobao.com
                           :scheme: https
                           :path: /?name=tbhs&cna=IAj9EOy3fngCAXBQ5kJ9yusH&nn=&count=13&pid=430266_1006&_ksTS=1491363551394_94&callback=jsonp95
                           user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
                           accept: */*
                           referer: https://www.taobao.com/
                           accept-encoding: gzip, deflate, sdch, br
                           accept-language: zh-CN,zh;q=0.8
                           cookie: [382 bytes were stripped]
                       --> parent_stream_id = 0
                       --> stream_id = 1
                       --> weight = 147
t=370256 [st=   31]    HTTP2_SESSION_RECV_SETTINGS
                       --> host = "textlink.simba.taobao.com:443"
t=370256 [st=   31]    HTTP2_SESSION_RECV_SETTING
                       --> flags = 0
                       --> id = 3
                       --> value = 128
t=370256 [st=   31]    HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE
                       --> delta_window_size = 2147418112
t=370256 [st=   31]    HTTP2_SESSION_RECV_SETTING
                       --> flags = 0
                       --> id = 4
                       --> value = 2147483647
t=370256 [st=   31]    HTTP2_SESSION_RECV_SETTING
                       --> flags = 0
                       --> id = 5
                       --> value = 16777215
t=370256 [st=   31]    HTTP2_SESSION_RECEIVED_WINDOW_UPDATE_FRAME
                       --> delta = 2147418112
                       --> stream_id = 0
t=370256 [st=   31]    HTTP2_SESSION_UPDATE_SEND_WINDOW
                       --> delta = 2147418112
                       --> window_size = 2147483647
t=370261 [st=   36]    HTTP2_SESSION_RECV_HEADERS
                       --> fin = false
                       --> :status: 200
                           date: Wed, 05 Apr 2017 03:39:11 GMT
                           content-type: text/html; charset=ISO-8859-1
                           vary: Accept-Encoding
                           server: Tengine
                           expires: Wed, 05 Apr 2017 03:39:11 GMT
                           cache-control: max-age=0
                           strict-transport-security: max-age=0
                           timing-allow-origin: *
                           content-encoding: gzip
                       --> stream_id = 1
t=370261 [st=   36]    HTTP2_SESSION_RECV_DATA
                       --> fin = false
                       --> size = 58
                       --> stream_id = 1
t=370261 [st=   36]    HTTP2_SESSION_UPDATE_RECV_WINDOW
                       --> delta = -58
                       --> window_size = 15728582
t=370261 [st=   36]    HTTP2_SESSION_RECV_DATA
                       --> fin = true
                       --> size = 0
                       --> stream_id = 1
t=370295 [st=   70]    HTTP2_STREAM_UPDATE_RECV_WINDOW
                       --> delta = 58
                       --> window_size = 15728640
t=402700 [st=32475] 

备注:

这篇文章摘抄来自网络。我打算总结一些列架构师需要的优秀文章,由于自己写会花太多时间,我决定做一个搬运工,为大家筛选优秀的文章,最后我会做成索引方便大家查找。

相关推荐

NUS邵林团队发布DexSinGrasp基于强化学习实现物体分离与抓取统一

本文的作者均来自新加坡国立大学LinSLab。本文的共同第一作者为新加坡国立大学实习生许立昕和博士生刘子轩,主要研究方向为机器人学习和灵巧操纵,其余作者分别为硕士生桂哲玮、实习生郭京翔、江泽宇以及...

「PLC进阶」如何通过编写SCL语言程序实现物料分拣?

01、前言SCL作为IEC61131-3编程语言的一种,由于其高级语言的特性,特别适合复杂运算、复杂数学函数应用的场合。本文以FactoryIO软件中的物料分拣案例作为硬件基础,介绍如何通过SCL来实...

zk源码—5.请求的处理过程一(http1.1请求方法)

大纲1.服务器的请求处理链...

自己动手从0开始实现一个分布式 RPC 框架

前言为什么要自己写一个RPC框架,我觉得从个人成长上说,如果一个程序员能清楚的了解RPC框架所具备的要素,掌握RPC框架中涉及的服务注册发现、负载均衡、序列化协议、RPC通信协议、Socket通信、异...

MLSys’25 | 极低内存消耗:用SGD的内存成本实现AdamW的优化性能

AIxiv专栏是机器之心发布学术、技术内容的栏目。过去数年,机器之心AIxiv专栏接收报道了2000多篇内容,覆盖全球各大高校与企业的顶级实验室,有效促进了学术交流与传播。如果您有优秀的工作想要分享,...

线程池误用导致系统假死(线程池会自动销毁吗)

背景介绍在项目中,为了提高系统性能使用了RxJava实现异步方案,其中异步线程池是自建的。但是当QPS稍微增大之后却发现系统假死、无响应和返回,调用方出现大量超时现象。但是通过监控发现,系统线程数正常...

大型乘用车工厂布局规划(六大乘用车基地)

乘用车工厂的布局规划直接影响生产效率、物流成本、安全性和未来扩展能力。合理的布局应确保生产流程顺畅、物流高效、资源优化,并符合现代化智能制造和绿色工厂的要求。以下是详细的工厂布局规划要点:1.工厂布...

西门子 S7-200 SMART PLC 连接Factory IO的方法

有很多同学不清楚如何西门子200smart如何连接FactoryIO,本教程为您提供了如何使用西门子S7-200SMARTPLC连接FactoryIO的说明。设置PC和PLC之间的...

西门子博图高级仿真软件的应用(西门子博途软件仿真)

1.博图高级仿真软件(S7-PLCSIMAdvancedV2.0)S7-PLCSIMAdvancedV2.0包含大量仿真功能,通过创建虚拟控制器对S7-1500和ET200SP控制器进行仿真...

PLC编程必踩的6大坑——请对号入座,评论区见

一、缺乏整体规划:面条式代码问题实例:某快递分拣线项目初期未做流程图设计,工程师直接开始编写传送带控制程序。后期增加质检模块时发现I/O地址冲突,电机启停逻辑与传感器信号出现3处死循环,导致项目延期2...

统信UOS无需开发者模式安装软件包
统信UOS无需开发者模式安装软件包

原文链接:统信UOS无需开发者模式安装软件包...

2025-05-05 14:55 csdh11

100个Java工具类之76:数据指纹DigestUtils

为了提高数据安全性,保证数据的完整性和真实性,DigestUtils应运而生。正确恰当地使用DigestUtils的加密算法,可以实现数据的脱敏,防止数据泄露或篡改。...

麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包

#秋日生活打卡季#原文链接:...

Java常用工具类技术文档(java中工具类的作用)

一、概述Java工具类(UtilityClasses)是封装了通用功能的静态方法集合,能够简化代码、提高开发效率。本文整理Java原生及常用第三方库(如ApacheCommons、GoogleG...

软路由的用法(自动追剧配置)(软路由教学)

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:值友98958248861环境和需求...