从文本到二进制:HTTP/2不止于性能,更是对HTTP/1核心语义的传承与革新
云原生计算基金会(Cloud Native Computing Foundation,CNCF)是一个非盈利的开源组织,专注于推动云原生计算的发展和标准化。而gRPC(Google Remote Procedure Call)是由Google发起并开源的高性能、跨语言RPC框架。2017年,Google将gRPC项目捐赠给了CNCF,使其成为云原生生态的核心组件之一。gRPC与Kubernetes(容器编排)、Prometheus(监控)、Istio(服务网格)等CNCF项目深度集成,广泛应用于微服务架构和云原生应用中,其重要性随着云原生理念的普及而日益凸显。
gRPC巧妙地结合了ProtoBuf、HTTP/2等成熟技术,为上述RPC三大问题提供了全面且标准化的解决方案。
1)数据表示:默认采用 ProtoBuf作为其IDL和高效的二进制序列化方案。
2)数据传递:建立在 HTTP/2 协议之上,利用其多路复用、流控、头部压缩等特性实现高效网络通信。
3)方法约定:通过 ProtoBuf IDL (.proto 文件) 定义服务接口和消息结构。
HTTP/2协议

HTTP/2是HTTP/1.1的重大升级版,其设计源于Google的SPDY协议,并于2015年正式成为标准(RFC 7540)。HTTP/1.1虽应用广泛,但其固有的性能瓶颈——如队头阻塞(Head-of-Line Blocking)、较高的连接建立延迟、低效的文本头部传输——已难以满足现代Web应用对高性能、低延迟的需求。HTTP/2旨在克服这些问题,显著提升传输效率和用户体验。
与HTTP/1.1的纯文本传输不同,HTTP/2引入了二进制分帧层 (Binary Framing Layer)。所有HTTP消息(请求/响应)都被封装成一个个二进制编码的帧 (Frame) 进行传输。这种设计不仅提高了处理效率和健壮性(解析二进制比文本更快更不容易出错),还为多路复用(Multiplexing)、头部压缩(Header Compression)和服务器推送(Server Push)等高级特性奠定了基础。
HTTP/2的核心架构包含以下几个关键概念。
1)Connection(连接):一个TCP连接支持多个并发Stream,减少了HTTP/1.1中多个TCP连接的开销和延迟。
2)Stream(流):独立的双向通信通道,用于传输一条或多条Message,避免了队头阻塞。
3)Message(消息):对应HTTP/1.1的请求或响应,由一个或多个Frame组成,使数据传输更灵活。
4)Frame(帧):最小的通信单位,采用二进制格式,包含元数据和有效载荷,用于客户端与服务器间的信息传递。

帧结构
帧是一种长度前缀消息(Length-Prefixed-Message)。帧以固定的9字节作为帧头,后面跟着变长的帧载荷(Frame Payload),帧头包括如下公共字段:Type、Length、Flags, Stream Identifier。
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
HTTP/2协议定义了10种不同类型的帧(Frame),其中通用格式包含以下几个关键类型,这些类型共同定义了帧的行为和内容。
1)Length(长度):表示帧载荷(Frame Payload)的长度,以字节为单位。其最大长度为2^14(即16384字节),不包括帧头的9个字节。
2)Type(类型):用于标识帧的类型。其中,DATA帧和HEADERS帧,分别对应于HTTP/1.1中的数据和头部信息。其他帧类型还包括SETTINGS、PRIORITY、RST_STREAM等,用于实现协议的各种高级特性。
3)Flags(标志):该字段包含一组标志位,用于传递帧的附加控制信息。常用的标志位包括: END_HEADERS:表示当前帧是头数据(Headers)的最后一帧,相当于HTTP/1.1中头信息结束后的空行(“\r\n”);END_STREAM:表示当前帧是流(Stream)中最后一个帧,标志着单方向数据传输的结束(End of Stream, EOS),相当于HTTP/1.1中分块传输编码(Chunked Encoding)的结束标志(“0\r\n\r\n”);PRIORITY:用于指示流的优先级,帮助服务器和客户端优化资源分配。
4)R(保留字段):该字段为保留位,目前未使用,必须设置为0。
5)Stream Identifier(流标识符):用于标识帧所属的流(Stream)。每个流都有一个唯一的标识符,用于在同一个TCP连接中区分不同的并发流。流标识符的长度为31位,其中客户端发起的流使用奇数标识符,服务器发起的流使用偶数标识符。
消息的语义兼容性
HTTP/2 协议与 HTTP/1尽可能保持兼容。从应用程序的角度来看,协议的功能基本没有变化。为了实现这一点,HTTP/1的所有请求和响应语义被保留,虽然传达那些语义的语法已经改变。
HTTP/1使用消息起始行(start-line)来传达目标 URI,请求方法和响应的状态代码,而HTTP/2为此使用以“:”字符开头的特殊字段(pseudo-header)来达到相同的目的。

可以看到在第一个请求中,前两个头通常类似与HTTP/1。
GET /resoure HTTP/1.1
Host: https://example.com
...
现在被拆分为一个标题框。
:method: GET
:scheme: https
:host: example.com
:path: /resource
...
而其余的头则大致相同,都是lower-case字符。
HTTP/2尝试尽可能地最小化有效载荷大小。它将压缩与前一个请求中相同的头。在HTTP/1中,一个连续的请求看起来像是针对不同资源的初始请求。
GET /otherResource HTTP/1.1
Host: https://example.org
...
而在HTTP/2中,对同一服务器的连续请求只需要:path头部信息。
:path: /otherResource
因为所有其他头部信息都被标记并压缩缓存,并且可以通过“索引”进行还原。
未完待续
很高兴与你相遇!如果你喜欢本文内容,记得关注哦!
从文本到二进制:HTTP/2不止于性能,更是对HTTP/1核心语义的传承与革新的更多相关文章
- 【python】3.x,string与bytes的区别(文本,二进制数据)
Python 3对文本和二进制数据作了更为清晰的区分.文本总是Unicode,由str类型表示, 二进制数据则由bytes类型表示. 不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也 ...
- jdbc基础 (三) 大文本、二进制数据处理
LOB (Large Objects) 分为:CLOB和BLOB,即大文本和大二进制数据 CLOB:用于存储大文本 BLOB:用于存储二进制数据,例如图像.声音.二进制文件 在mysql中,只有B ...
- 《Python CookBook2》 第一章 文本 - 过滤字符串中不属于指定集合的字符 && 检查一个字符串是文本还是二进制
过滤字符串中不属于指定集合的字符 任务: 给定一个需要保留的字符串的集合,构建一个过滤函数,并可将其应用于任何字符串s,函数返回一个s的拷贝,该拷贝只包含指定字符集合中的元素. 解决方案: impor ...
- 文件操作总结:关于文本和二进制流(typeText&typeBinary)
本人能力.精力有限,所言所感都基于自身的实践和有限的阅读.查阅,如有错误,欢迎拍砖,敬请赐教——博客园:钱智慧. 总结: CFile,其自身是不提供缓冲区的(?但CFile又有一个Flush,这一点目 ...
- netty实现websocket发送文本和二进制数据
原文:https://huan1993.iteye.com/blog/2433552 最近在学习netty相关的知识,看到netty可以实现 websoket,因此记录一下在netty中实现webso ...
- 2019-9-2-C#判断文件属于文本或二进制
title author date CreateTime categories C#判断文件属于文本或二进制 lindexi 2019-09-02 12:57:37 +0800 2018-2-13 1 ...
- 文本IO 二进制IO
一.文本IO 字符流 使用PrintWriter写入文件后,必须调用close(),否则数据不能正确保存在文件中. Scanner的next()读取一个由分隔符分隔的字符串,nextLine()读取 ...
- 文本与二进制关于\n的问题
文本文件中: text = open(path, "r");windows中的换行符\n,在文件中windows在存储的时候会将它看成\r\n存储,用r在读取大小时会忽略\r的大小 ...
- VR技术赋能五大领域,不止高级,更高效!
除了VR游戏.VR影视作品,究竟还有哪些产业领域会应用到VR技术并为生活带来改变呢?今天就帮大家好好梳理一下~ VR赋能交通,不只是高级 最近在网上看到了VR考驾照的新闻,网友都赞叹,现在学车都这么高 ...
- Apache与Tomcat负载均衡
Apache HTTP Server 与 Tomcat 的三种连接方式JK,http_proxy,ajp_proxy.下面逐个介绍一下(本篇介绍的示例都是基于前面介绍的已经搭建好的Tomcat集群,都 ...
随机推荐
- mysql练习题版本一
有些题还没有解决 -- 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数 1.1 查询同时存在" 01 "课程和" ...
- 江铃晶马 X 袋鼠云:搭建企业级数据资产中心,推进打造“智数晶马”
江铃集团晶马汽车有限公司(简称:晶马汽车)系江铃集团全资子公司,属集团六大整车企业之一.晶马汽车是以大.中.轻型客车(含新能源客车).乘用车(不含轿车).专用车等车型研发.生产.销售和服务为核心的整车 ...
- Blazor学习之旅(4)数据共享
本篇,我们来了解下在Blazor中数据是如何共享的,组件之间又该如何传递参数. 关于Blazor组件 在 Blazor 中,从名为"组件"的自包含代码部分生成 UI.每个组件都可以 ...
- Oracle中的函数与存储过程
自定义函数 函数的最大特征是必须返回值 创建自定义函数 创建函数使用create or replace function命令 create or replace function 函数名 return ...
- java基础--自定义异常类、包、模板模式
自定义异常类 需求: 模拟feiQ上线的时候,如果没有插上网线,那么就抛出一个没有插上网线的异常, 如果已经插上了网上,那么就正常显示好友列表. 自定义异常类的步骤: 自定义一个类继承Exceptio ...
- CF576A Vasya and Petyas Game 题解
CF576A Vasya and Petya's Game 数论思维题. 根据唯一分解定理,可以知道,如果一个数的各个质因数的数量确定了,这个数也就确定了. 每次询问的中,如果 \(x\) 是 \(y ...
- AtCoder Beginner Contest 214 ABCDE 题解
A - New Generation ABC 思路:分段讨论 view code #include<iostream> #include<string> #include< ...
- 研究生 华为杯数学建模F题
简介 以作记录不做说明. code https://github.com/lishaohsuai/mathmatic_hw
- AI-Compass宝藏资源库:构建最全面的AI学习与实践生态,服务AI全群体
AI-Compass宝藏资源库:构建最全面的AI学习与实践生态,服务AI全群体 AI-Compass将为你和社区提供在AI技术海洋中航行的方向与指引.无论你是刚踏入AI领域的初学者,还是寻求技术突破的 ...
- 01-Ble 协议栈分层
一.协议栈结构 如上图所示,蓝牙协议分为Controller和Host两个部分,Controller为蓝牙底层,为蓝牙物理芯片,Host是真正意义上的蓝牙协议.Profiles(配置文件)总是基于GA ...