当前位置: 首页 > news >正文

Http2多路复用的静态表和动态表

  1. 静态表:即插即用,无需学习,立竿见影的压缩

    • 内容:静态表是预先定义好的,包含了那些几乎在所有 HTTP 通信中都会高频率出现的、最最通用的头部字段及其常见值。例如:

      • ​:method: GET​
      • ​:scheme: http​
      • ​accept: */*​
      • ​content-type: application/json​
      • 等等,大约有61个条目。
    • 优点:

      • 无需协商,立即生效:客户端和服务器都知道这个静态表的内容。从连接建立的第一个请求开始,如果头部匹配静态表中的条目,就可以直接用一个非常小的索引号来表示,立即实现压缩,不需要任何“学习”或“同步”的过程。
      • 最小化初始开销:如果完全依赖动态表,那么即使是像 :method: GET​ 这样极其常见的头部,在第一次出现时也需要完整发送(或者至少是字面量发送并指示添加到动态表),这会增加初始请求的体积。静态表避免了这个问题。
      • 永远可用:静态表的内容是固定的,不会被“挤出去”,确保了对这些核心常用头的持续高效压缩。
  2. 动态表:按需学习,个性定制,更高压缩潜力

    • 内容:动态表是在每个 HTTP/2 连接的生命周期中,由客户端和服务器共同动态构建和维护的。它可以存储那些在特定会话中频繁出现,但并非普遍通用的头部,或者是静态表中已有头部但值不同的情况。

      • 例如,一个特定的 Cookie​ 值,或者一个不常见的自定义 X-Custom-Header​。
    • 优点:

      • 自适应压缩:能够学习并压缩那些在当前通信场景下重复出现的头部,即使这些头部不在静态表中。
      • 对变化值的处理:即使头部名称在静态表中,但如果值经常变化(比如某些 ETag​ 值),动态表可以记住这些新的“名称-值”对。
      • 更高的潜在压缩率:对于特定会话中大量重复的非静态头部,动态表提供了非常高的压缩潜力。

为什么两者共存是最佳方案?

  • “冷启动”效率 vs. “持续运行”效率:

    • 静态表保证了“冷启动”效率:连接刚建立时,动态表是空的。此时,静态表能立刻对最常见的头部进行压缩,避免了最初几个请求头部过大的问题。
    • 动态表提供了“持续运行”的更高效率:随着通信的进行,动态表会学习并填充那些特定于当前会话的重复头部,从而在后续请求中达到比仅使用静态表更高的压缩率。
  • 开销与收益的平衡:

    • 静态表开销极低:使用静态表条目只需发送一个小索引。
    • 动态表有维护开销:向动态表添加条目、管理其大小(动态表有最大容量限制,旧条目可能被逐出)、以及确保两端同步,这些都需要额外的信令开销。如果所有头部都依赖动态表,那么对于那些极度常见且固定的头部(如 :method: GET​),每次都通过动态表机制来处理反而显得“小题大做”且效率不高。
  • 覆盖范围与特异性的结合:

    • 静态表提供基础覆盖:覆盖了绝大多数通信都会用到的“基础词汇”。
    • 动态表提供特异性覆盖:捕捉和压缩了特定对话中的“流行语”或“个性化表达”。

打个比方:

想象一下你在学习一门新语言(HTTP 通信):

  • 静态表就像是语言中最基础、最高频的100个单词(比如“你”、“我”、“是”、“好”、“谢谢”)。你一开始就应该掌握它们,并且用最简洁的方式表达(比如只用一个手势或一个音节——索引号)。这样你一开始就能进行最基本的沟通,而且非常高效。
  • 动态表就像是你和特定朋友聊天时,你们之间形成的一些常用语、昵称或者针对特定话题的术语。这些词可能不是普遍通用的,但你们俩之间用得很多。你们会在聊天过程中逐渐“约定”这些词的简称(添加到动态表),后续沟通中就能用这些简称来提高效率。

如果只有动态表,那你每次和新朋友(新的 HTTP/2 连接)说话,连最基本的“你好”、“谢谢”都得先完整说一遍,并告诉对方“下次我们用‘H’代表你好,‘X’代表谢谢”,这就很低效。

如果只有静态表,那对于你们朋友间特有的常用语,你就没法用简称,只能每次都完整重复,压缩效果就受限了。

因此,静态表和动态表结合使用,HPACK 才能既保证初次通信的即时压缩效率(针对通用头部),又能通过学习机制在后续通信中对会话特定的重复头部实现更高的压缩率,从而达到整体最优的头部压缩效果。

相关文章:

  • 假如你的项目是springboot+vue怎么解决跨域问题
  • 软考冲刺——案例分析题Super VLAN
  • 优秀的流程图设计软件【留存】
  • 0基础学AI智能体,Coze和Dify该学那个?有什么区别吗?
  • JVM规范之运行时数据区域
  • 文件批量重命名工具,简单高效一键完成更名
  • Spring AI(3)——Chat Memory
  • 【Java学习日记34】:this关键字和成员变量
  • 本贴会成为记录贴
  • 巧用promise.race实现nrm镜像源切换----nbsl
  • # 2-STM32-复位和时钟控制RCC
  • Python中的标识、相等性与别名:深入理解对象引用机制
  • 【C语言】程序的预处理,#define详解
  • Vue.js 页面切换空白与刷新 404 问题深度解析
  • C++开发过程中的注意事项详解
  • 基于Qt的app开发第七天
  • 【软件测试】基于项目驱动的功能测试报告(持续更新)
  • 双向循环神经网络(Bi-RNN)详解
  • 1688 开放平台接口对接实战:商品实时数据采集 API 开发全流程
  • 了解窗口系统
  • 宁德时代港股募资预计最高至50亿美元:90%将投向匈牙利项目
  • 深一度|在亚马尔的天才面前,姆巴佩戴上“帽子”又如何
  • 西藏日喀则市拉孜县发生5.5级地震,震源深度10千米
  • 10名“鬼火少年”凌晨结队在城区飙车,警方:涉非法改装,正处理
  • 陈宝良 高寿仙 彭勇︱明清社会的皇权、商帮与市井百态
  • 非洲雕刻艺术有着怎样的“变形之美”