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

【Envoy 数据面】Network filter 与 Connection:字节流、水印与 TCP Proxy / HCM 分叉

文章导航

分类入口
networkproxy
标签入口
#envoy#network-filter#connection#watermark#tcp-proxy#http-connection-manager#v1.39

目录

上一篇把连接送进某条 FilterChain。本篇问:链上的 network filter 看见的是什么? 它们操作的是原始字节与少量连接事件,而不是 HTTP header map。把 L4 与 L7 入口混为一谈,会在排障时从 Router 找「TCP 断连」原因。

本文依据 v1.39.0 Listener filters 文中的 Network (L3/L4) filtersTCP proxy filter 叙述,钉住 filter 类型、连接生命周期、缓冲水印反压,以及 TCP Proxy vs HCM 分叉。

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

篇目 核心内容
第 3 篇 · Listener Match 选哪条链
第 4 篇 · Network Filter 字节流、水印、TCP Proxy / HCM
第 5 篇 · HCM Codec HTTP 事件与编解码
第 8 篇 · Conn Pool 上游连接资源限额

版本锚定:Envoy v1.39.0 Network (L3/L4) filtersTCP proxy filter;API v3 TcpProxy / HttpConnectionManager;源码 source/common/network/source/extensions/filters/network/


一、Network filter:三类与组合语义

官方把 network filters 写成连接处理的核心:同一 listener 下不同 filter_chain 可挂不同有序列表。类型三分:

类型 触发 典型用途
Read 下游数据到达 解析、限流、检测
Write 即将写回下游 改写、计量
Read/Write 双向 TLS、代理、HCM

过滤器可 stop / continue 迭代,以便同步或异步调用外部服务后再放行。同一下游连接的 network filters 之间可共享静态与动态状态(官方 data sharing between filters)——状态作用域是单连接,不是跨 Worker 全局。

这与 HTTP filter 的关键差别:输入是字节与连接事件(TLS 握手完成、本地/远端断开等),不是「headers received」。HCM 本身是一个 network filter:它把字节翻译成 HTTP 事件,再把控制交给 HTTP filter 链。


二、Connection 生命周期(数据面视角)

stateDiagram-v2
  [*] --> Accepted: accept and match chain
  Accepted --> FilterInit: instantiate filters
  FilterInit --> Open: onNewConnection
  Open --> Reading: downstream data
  Open --> Writing: upstream or local write
  Reading --> Open
  Writing --> Open
  Open --> Closing: local or remote close
  Closing --> [*]: filters torn down

简化阶段(机制叙述,非逐函数源码 trace):

  1. 实例化:按选中 chain 创建 filter 栈与 Connection 上下文。
  2. 数据面循环:读事件 → Read 过滤器;上游或本地产生写 → Write 过滤器;事件回调在绑定该连接的 Worker 上执行(见第 2 篇)。
  3. 半关闭与整关闭:TCP 半关闭、reset、空闲超时、filter 主动关连接,都会驱动栈拆除;具体超时字段因 filter(TcpProxy vs HCM)而异。
  4. 与上游的关系:TCP Proxy 维持近似 1:1 的下游—上游连接;HCM 则在请求级向 cluster 借连接池中的上游连接(池化细节第 8 篇)。

失败模式:在 network 层关闭连接,access log / HTTP 统计可能从未看到「请求」——因为请求语义尚未诞生。TLS 握手失败、idle timeout、下游 reset,都会在进入 HCM 之前终止——排障清单应先问「连接是否活到过 network filter 的 onNewConnection」。

同一 Worker 上其他连接共享事件环:一条连接上的重 filter(例如同步调用外部授权)会推迟同线程其他连接的读写。这不是全局锁,但是线程级队头阻塞;与第 2 篇 Watchdog /「连接钉死 Worker」同根。


三、缓冲与水印:反压而不是无限队列

Envoy 连接带有读写缓冲。当缓冲超过高水位,连接进入 watermark 状态,通常停止继续读下游或通知过滤器「该减速」;落到低水位再恢复。目的是:慢消费者不能无限吃内存,并把压力传回对端或上游写路径。

本篇不下伪造阈值或「默认多少字节」——具体 per_connection_buffer_limit_bytes 等以当版配置与运行时为准。机制结论只需记住:

争论落点:用户态代理用显式水位模拟「背压」;内核 eBPF L4 转发往往不解析应用层,也没有同构的「HTTP 流水位」。选型时比较的是语义深度,不是抽象的「谁更快」。

与 overload / 连接限额的关系:水印是单连接的内存保险丝;cluster 连接上限与 listener connection limit 是资源配额。两者同时打满时,症状叠加(新连接拒、旧连接停读),归因要拆开看 stats 命名空间,而不是只盯一个 counter。


四、分叉 A:TCP Proxy

TCP proxy filter:下游与上游 cluster 之间做基本 1:1 连接代理,可单独作 stunnel 类用途,也可与 Mongo 嗅探、限流等 filter 组合。

关键不变量:

排障时若链路配置的是 tcp_proxy,却在 HTTP access log / :path 维度找原因——坐标系错了。连接上限打满时的表现是「下游能连上 Envoy,但建不起上游」——与 HCM 的 503 语义相邻但指标不同,应用 cluster 连接类计数区分。


五、分叉 B:通向 HCM 的路径

http_connection_manager 作为 network filter 挂在 chain 上时,后续世界切换为:

bytes → codec → HTTP streams → http_filters → Router → cluster pool

同一 listener 上可以一条链 TCP Proxy、另一条链 HCM(靠第 3 篇的 match)。「一切皆 HTTP filter」在工程上不成立:L4 专用路径更短、语义更少;强行把二进制协议塞进 HCM 只会制造伪 HTTP 与错误 codec。

flowchart TB
  Chain["Selected filter chain"] --> TP["tcp_proxy"]
  Chain --> HCM["http_connection_manager"]
  TP --> L4["1:1 upstream connection"]
  HCM --> Codec["HTTP/1 2 3 codec"]
  Codec --> HF["HTTP filters"]
  HF --> R["Router"]

谱系:可编程中间盒把「可插拔字节过滤器」做成组合点(Envoy network filter);HTTP/2 普及后,多数服务网格流量走 HCM,导致文档与示例偏 L7。开放问题仍在:非 HTTP 上游(Redis、Kafka、自有 RPC)应留在 L4/专用 network filter,还是用 tunnel / CONNECT 升到 HTTP——第 5、13 篇边界触及,本篇只固定分叉点。

失败对照(同端口、不同 chain):

配置终点 成功长什么样 失败常被误读成
tcp_proxy 字节对拷、无 HTTP 状态码 「没有 200」其实从未进入 HCM
http_connection_manager 有 codec / stream / 路由统计 「TCP 通了」但 ALPN 错导致全协议错误

两行表的用途只有一个:写告警与 runbook 时先钉链终点类型,再选指标。


六、同链多 filter 时的顺序直觉

常见模式(示意):

  1. 可选:网络限流、RBAC(网络级)、Mongo 等协议 filter;
  2. 终端:tcp_proxy http_connection_manager(通常二选一作「消费连接」的终点)。

顺序错误的典型后果:在 HCM 之后再挂期望读原始字节的 filter——字节已被 codec 消费,行为未定义于「直觉上的透明串联」。配置审查先找谁终结字节流

另一个常见误配:同一 chain 里既想「透传 TCP」又想「看 HTTP 头做路由」——做不到干净折中。正确做法是 FilterChainMatch 分成两条链(或上游协议专用 filter),而不是指望 network filter 列表线性「又透传又解码」。


七、参考资料

规范 / 官方文档(A)

源码(A)

站内对照

实验台账


八、小结

  1. Network filter 吃字节与连接事件;HCM 是其中把世界升级到 HTTP 的那一个。
  2. 水印提供用户态反压;慢客户端 / 慢上游首先打满的是缓冲语义,不一定是路由表。
  3. TCP Proxy = 1:1 L4HCM = 编解码 + HTTP filter + Router——选错坐标系会排错层。
  4. 下一篇专讲 HCM:codec、stream 与连接生命周期、编解码错误如何浮现。

上一篇:Listener 与 FilterChainMatch · 系列目录 · 下一篇:HCM 与 Codec

同主题继续阅读

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


By .