土法炼钢兴趣小组的算法知识备份

【Envoy 数据面】HCM 与 Codec:HTTP/1·2·3、流生命周期与编解码错误

文章导航

分类入口
networkproxy
标签入口
#envoy#http-connection-manager#codec#http2#http3#stream#v1.39

目录

上一篇把路径分到 http_connection_manager。本篇进入 L7 入口:HCM 做什么、codec 做什么、stream 与 connection 为何不能混称。 把 HTTP/1 流水线、HTTP/2 多路复用、HTTP/3/QUIC 都当成「同一个 socket 上的同一个请求对象」,会在超时、重置与连接复用上误判。

依据 v1.39.0 HTTP connection management:HCM 是内置 network filter;codec API 把不同线协议译成协议无关的 stream / request / response 形态。

本文是「Envoy / 数据面代理内核」系列第 5 篇(共 16 篇)。→ 系列目录

篇目 核心内容
第 4 篇 · Network Filter 字节流与通向 HCM 的分叉
第 5 篇 · HCM Codec 编解码、流生命周期、错误
第 6 篇 · HTTP Filter Router 过滤器顺序与终端路由
第 8 篇 · Conn Pool 上游协议池与复用

版本锚定:Envoy v1.39.0 HTTP connection managementHTTP/3 overviewConnection pooling;源码 source/common/http/source/extensions/filters/network/http_connection_manager/


一、HCM:HTTP 连接的「操作系统」

官方定位:HTTP Connection Manager 把原始字节翻译成 HTTP 级消息与事件(headers / body / trailers received 等),并承担所有 HTTP 连接与请求共性工作:access log、request ID、tracing、首部处理、路由表管理、统计等。

路由表来源二选一:静态,或 RDS 动态下发。重试插件、内部重定向、超时等也挂在 HCM / 路由配置上——细节第 6 篇展开;本篇只钉「事件从哪来」。

安全相关:HCM 会做 header sanitizing;不可信下游首部清理与「过滤器再改一次首部」的交互,在内部重定向文档里有明确警告(清理只完整适用一次等)——配置 header 操作时要当一等风险。

HCM 持有的路由表是该 HCM 实例的视图:静态嵌在 typed_config 里,或经 RDS 订阅。多 listener / 多 HCM 并不自动共享一张表——「改了 RDS 为何这个口没变」首先核对哪个 HCM 订了哪个 route config name,而不是先怀疑 TLS 快照失灵。


二、Codec:线协议 → 协议无关 stream

设计目标(官方原文要点):Envoy HTTP 支持首先按 HTTP/2 多路复用代理来设计;内部用 HTTP/2 术语描述组件——一次请求/响应发生在一条 stream 上。

flowchart LR
  Wire["Wire bytes"] --> C1["HTTP/1 codec"]
  Wire --> C2["HTTP/2 codec"]
  Wire --> C3["HTTP/3 codec"]
  C1 --> Agg["Protocol-agnostic streams"]
  C2 --> Agg
  C3 --> Agg
  Agg --> HCM["HCM + HTTP filters"]
协议 Codec 职责摘要 对上层的「样子」
HTTP/1.1 把串行 / pipelining 译成类 HTTP/2 的 stream 视图 多数代码不感知起源协议
HTTP/2 帧、流 ID、HPACK、SETTINGS / GOAWAY 等 原生多路复用
HTTP/3 QUIC 上的 HTTP;与 TCP 路径分叉 仍映射到同一套 stream 事件

codec_type(如 AUTO)决定如何选下游 codec;上游协议由 cluster 的 HTTP 协议选项 / 连接池决定(Connection pooling)。下游是 h2、上游是 h1 是常态:stream 在 HCM 内扇出到不同池。

WebSocket、CONNECT、TCP/UDP over HTTP 等升级路径见官方 HTTP upgrades——本篇不展开,只强调:它们仍先经过「能说话的 codec + HCM」,不是另一条旁路 Listener 魔法。

HCM 还统一做 request ID 生成与 tracing 注入点:编解码成功之前,这些字段往往尚未稳定。因此「没有 request id 的断开」更可能是 listener / network / codec 前期失败,而不是 Router 没打日志。


三、Stream vs Connection

对象 是什么 销毁/结束常见条件
Connection 下游(或上游)传输会话;HTTP/1 常 1 请求序列,H2/H3 多 stream 空闲超时、GOAWAY、reset、对端关闭、排水
Stream 一条请求—响应逻辑通道 见下方 lifecycle;错误或超时可提前结束

HTTP lifecycle(v1.39.0)要点:

排障含义:H2 下「连接还在、单 stream 已 reset」与 H1 下「连接直接断」不是同一症状;日志里应区分 connection 级与 stream 级字段。

把 lifecycle 两条分支写成检查表:

  1. 上游是 H1 吗?→ 响应结束即可拆 stream,未完成的请求侧可能被 reset。
  2. 上游是 H2/H3 且开启 independent half-close 吗?→ 两侧 end-stream + 成功响应才拆。
  3. 是否超时 / 对端 reset?→ 代理可提前停,与「正常生命周期」并列,不是互斥。

漏掉第 1 条去调 H2 半关闭参数,是常见的配置空转。


四、Codec 与协议错误模式

症状 可能落点 说明
连接建立后立即协议错误 下游 codec 选错 / ALPN 与 chain 不匹配 回到第 3 篇 SNI/ALPN
部分请求 503,连接仍活 单 stream 失败或上游池限额 连接≠全部 stream 健康;见第 8 篇
上传未完成响应已结束 half-close / H1 上游生命周期 对照官方 lifecycle 两条分支
H3 回落 H2/H1 UDP 被拦或 Alt-Svc 缺失 Connection pooling / HTTP/3 文:UDP 阻断常见;自动选择有 TCP 故障转移语义
首部相关安全问题 sanitizing 与 filter 改写顺序 勿假设「每个 filter 都看到原始下游头」

上游池侧(官方 Connection pooling):H1 池不靠 pipelining 绑多请求到一连接以免级联 reset;H2/H3 池在 max concurrent streams、GOAWAY、每连接请求上限下排水并开新连接。每个 Worker 各自维护 pool——与第 2 篇 shared-nothing 一致。多协议 cluster 在非 ALPN 场景下可能每协议一池;再乘 Worker 数,池实例数会快速上升——这是内存与 FD 规划问题,不是「开了 h2 就一定更省连接」。

自动协议选择(正向代理常见 AutoHttpConfig):TCP + ALPN 在 H2/H1 间择优;掺 H3 时依赖 alternate protocol 缓存 / Alt-Svc 等广告,并可能对 QUIC 与 TCP 做短窗口并行尝试。机制允许回落;观测上必须能区分「从未尝试 H3」与「尝试失败后回落」,否则会把网络 UDP 策略误判成「Envoy 不支持 H3」。


五、谱系、争论与开放问题

谱系:HTTP/2(RFC 7540 一系)把多路复用变成代理内核的默认心理模型;Envoy 用 codec 把 H1「抬」到同一抽象,避免为三套协议写三套 filter。HTTP/3/QUIC 把传输从 TCP 挪到 UDP,强制数据面出现第二条监听与故障转移经济学

争论

开放问题

  1. H3 在中间盒 / 企业网上的可达性与「假失败」观测(官方仍强调 UDP 阻断与回落路径的生产验证)。
  2. 独立半关闭默认策略与上游协议矩阵,如何在平台层给统一超时语义(避免每条 route 一套隐式假设)。
  3. Codec 错误相对 HTTP filter 错误的可观测字段是否足够——第 14、15 篇收束。

工程间隙:规范描述帧与流;生产还要加连接池熔断、重试、outlier。HCM 只保证「事件进 filter 链」;会不会打到健康上游是第 7–8 篇。

对本系列读者的收束句:第 3 篇选对链、第 4 篇选对终点、第 5 篇选对 codec 视图——三者任一失败,第 6 篇的 Router 再正确也救不了。最小联调路径因此是 03 → 04 → 05 → 06,而不是从 RDS 路由表倒查。


六、下一篇预告

Codec 解出 headers 之后,请求进入 HTTP filter 链Router 通常是终端过滤器,负责选 cluster、触发上游请求。过滤器顺序、短路、与重试/超时落点见第 6 篇。

超时与重试在文档中分属 HCM / route 配置;本篇不展开数值默认值。需要记住的只有:超时时钟挂在哪一层对象(连接 vs stream vs 路由尝试)上,决定你该看哪类 stats——具体字段表留给第 6、15 篇。


七、参考资料

规范 / 官方文档(A)

源码(A)

站内对照

实验台账


八、小结

  1. HCM 把字节变成 HTTP 事件,并承载日志、追踪、路由表、统计等共性能力。
  2. Codec 屏蔽 H1/H2/H3 线差异;上层以 stream 思维工作,但仍须按协议理解销毁与 reset。
  3. Connection 存活 ≠ 所有 stream 成功;half-close 与上游协议决定流何时结束。
  4. 编解码与 ALPN/选链错误要先排除,再怀疑 Router——下一篇进入 HTTP filter 与 Router 终端。

上一篇:Network filter 与 Connection · 系列目录 · 下一篇:HTTP filter 链与 Router

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。


By .