网关告警常说「Envoy 5xx 升了」,却说不清是下游连不上、上游池耗尽,还是路由仍指向旧 cluster。可观测信号若脱离请求路径,只能得到「代理不健康」——得不到「卡在哪一层」。
本文是「Envoy / 数据面代理内核」系列第 14 篇,只做三件事:
- 把 stats / access log / tracing 挂回第 1 篇的请求路径轴与上游资源轴。
- 用归因边界表说明每种信号能钉什么、钉不住什么。
- 给出 admin 统计树的概念地图;指标方法论、存储与 SLO 留给姊妹系列。
本文是「Envoy / 数据面代理内核」系列第 14 篇(共 16 篇)。→ 系列目录
篇目 核心内容 第 13 篇 · 扩展边界 Wasm / ext_authz / ratelimit 落点 第 14 篇 · 可观测数据面 路径耦合、归因边界、admin 统计树 第 15 篇 · 生产排障 无上游、warming、证书、泄漏清单
版本锚定:Envoy v1.39.0 Statistics / Access logging / Tracing / Administration interface。本文只写机制与命令语义;未在本机跑通的
/stats输出不粘贴。站内 可观测性工程 是姊妹系列——埋点哲学、时序库与 SLO 不在此重写。
一、三种信号,同一条路径
官方把统计粗分为 Downstream / Upstream / Server(Statistics overview)。落到数据面,它们对应第 1 篇坐标系的不同轴:
flowchart LR
accept["accept"] --> match["FilterChainMatch"]
match --> hcm["HCM / Codec"]
hcm --> filters["HTTP filters"]
filters --> router["Router"]
router --> pool["Upstream pool"]
hcm -.->|"access log + span"| obs["Obs signals"]
router -.->|"upstream_* stats"| obs
pool -.->|"cluster.* stats"| obs
| 信号 | 挂载点(概念) | 粒度 | 主用途 |
|---|---|---|---|
| Stats | listener / HCM / cluster / server 计数器、量规、直方图 | 聚合 | 告警、容量、趋势 |
| Access log | HCM / TCP Proxy 等在请求结束时格式化 | 单请求 | 事后复盘、RESPONSE_FLAGS |
| Tracing | HCM tracing;采样后上报 span |
采样子集 | 跨跳延迟与父子关系 |
三者都不是「旁路探针」:它们在 Worker
热路径或请求收尾处取值。采样率、日志字段、histogram
刷新间隔都会改成本——但语义仍绑定路径上的对象名(stat_prefix、cluster
name、route decorator)。
二、Stats:能看到层,看不到单次因果
2.1 Downstream vs Upstream vs Server
- Downstream:入口侧——listener、HCM、TCP Proxy 上的连接/请求计数与延迟直方图。
- Upstream:出口侧——连接池、Router、上游请求时间与结果码。
- Server:进程级——uptime、内存、热重启代数等,描述「这个 Envoy 实例」而非某一条流。
单跳排障的典型读法是:同一时间窗口对照 downstream
结果码与 upstream 结果码。downstream
rq_5xx 升而 upstream
几乎无请求,多半还在匹配/路由/本地回复;两边同升,再查
cluster 池与 outlier(→ 第
8 篇、第 15
篇)。
2.2 Admin 统计树(概念)
Admin GET /stats(及
format=prometheus)导出分层点分名。排查时先按前缀缩小,而不是通读全树:
| 前缀(示意) | 回答什么 |
|---|---|
listener.<name>. /
listener_manager. |
是否在收连接、listener 更新是否卡住 |
http.<stat_prefix>. |
HCM 请求量、响应码类、编解码、tracing 决策计数 |
cluster.<name>. |
上游健康、连接池、熔断溢出、outlier 驱逐 |
server. |
进程存活、内存、热重启世代 |
runtime. |
运行时开关是否被改过 |
HCM 文档把 tracing 决策计数钉在
http.<stat_prefix>.tracing.*(如
random_sampling、not_traceable、health_check)。这些是采样决策计数,不是「业务延迟根因」。
直方图默认按 stats_flush_interval
批量刷新;stats_flush_on_admin 可在查
/stats 时冲刷。没有本机 scrape
结果时,只把上述行为当协议语义,不虚构分位数。
Sink 侧(statsd、DogStatsD、Hystrix、metrics service
等)改变的是导出形状,不改变「谁在路径上递增计数器」。排障时先读本地
/stats 树,再争论远端 TSDB 方言。
2.3 Stats 钉不住什么
- 钉不住「哪一条路由配置版本」——要看 config_dump / xDS ACK 与 warming 状态。
- 钉不住单请求的 header 级因果(除非另开 access log / tap)。
- 高基数自定义 tag 会把时序库打爆——治理见 可观测性 · 埋点哲学,本文不展开。
- 钉不住「扩展 filter 内部逻辑」——Wasm / ext_authz 失败往往只表现为通用 5xx 或外呼超时,需要扩展专属统计或 access log 字段(第 13 篇)。
三、Access log:单请求真相,但事后且有成本
Access log 挂在 HCM(以及 TCP/UDP/Thrift
Proxy)配置上,在请求结束时用 substitution formatter
写出。默认格式串包含
%RESPONSE_FLAGS%、%DURATION%、%UPSTREAM_HOST%、%RESPONSE_HEADER(X-ENVOY-UPSTREAM-SERVICE-TIME)%
等(Access logging,v1.39.0)。
对排障最值钱的通常是:
| 字段族 | 用途 |
|---|---|
RESPONSE_FLAGS |
本地失败分类(无健康上游、超时、重置等)——第 15 篇清单的入口 |
DURATION vs upstream service time |
区分「代理内耗时」与「上游耗时」口径(字段含义以文档为准) |
UPSTREAM_HOST / cluster |
最终选中的上游 |
X-REQUEST-ID |
与 tracing / 应用日志对齐的钥匙 |
Access log 能回答「这一次请求在代理侧被标成什么失败」;不能单独证明控制面「已经 ACK 的配置」是否已对全部 Worker 生效——那是 xDS 一致性轴。全量 JSON access log 在高 QPS 下是存储与 CPU 税;生产默认应配合采样、过滤器(按状态码/路由)或按 listener 开启,而不是「开了就完事」。
TCP Proxy 路径同样可挂 access
log,但字段语义偏连接级,缺少 HTTP 路由维度——L4 排障不要期待
%RESPONSE_FLAGS% 给出与 HCM
相同的分类粒度。
四、Tracing:跨跳相关,默认抽样
官方 Tracing 概述:HCM 需配置
tracing;发起方式包括随机采样、x-envoy-force-trace、外部
x-client-trace-id 等。Envoy 生成/传递
x-request-id,并向 Zipkin / Jaeger / Datadog /
SkyWalking / OpenTelemetry 等 provider 上报 span。
关键边界:
- 上下文要业务传播。仅靠入站 sidecar 打
SERVER span、出站打 CLIENT span,中间应用若不转发 trace
header /
x-request-id,链路会断。 - 采样子集。
http.<stat_prefix>.tracing.not_traceable升不等于错误率升。 - 部署形态改 span 语义。Sidecar
常把「入站代理 + 应用 + 出站代理」看成一跳;网关或
spawn_upstream_span打开时,Envoy 更像独立跳。选型含义见第 16 篇,不在此做产品推荐。
完整采样策略、OTLP 管道与成本模型 → 可观测性 · Traces / OpenTelemetry。本篇只钉:Envoy span 描述的是代理跳上的 HTTP/gRPC 元数据,不是应用内部函数栈。
与 access log 的协作方式:用
x-request-id(或 provider 的 trace
id)把未采样请求的失败分类和已采样请求的跨跳火焰钉在同一把钥匙上;不要期望
tracing 覆盖每一次 503。
五、归因矩阵与姊妹系列分工
| 问题 | 优先信号 | 不够时补什么 |
|---|---|---|
| 哪一层 5xx / 溢出? | cluster.* / http.* stats |
access log RESPONSE_FLAGS |
| 单次请求选了谁、为何失败? | access log | /config_dump、/clusters |
| 跨服务谁拖慢? | tracing(已采样) | 上下游 RED 指标 |
| 配置是否仍在 warming? | listener/cluster 更新相关 gauge + config_dump | → 第 11、15 篇 |
| 进程是否在热重启排水? | server.hot_restart_generation 等 |
→ 第 12 篇 |
| 站内内容 | 负责 | 本篇不重复 |
|---|---|---|
| 可观测性工程 | 支柱、存储、SLO、事故剧本 | Envoy 路径落点 |
| network/57 | 运维入口地图 | 归因边界与失败模式 |
| 本系列 03–08 | 匹配、HCM、池化机制 | 观测字段如何映射回机制 |
争论(有文档边界、无虚假排名):全量 access log 换可审计性,还是高采样 tracing 换跨跳视野?工程上二者互补——stats 保告警,log/trace 保复盘;用延迟排行榜代替归因是本系列明确拒绝的写法。
六、参考资料
规范 / 官方文档(A)
- Envoy Proxy v1.39.0,Statistics(Downstream / Upstream / Server;counter / gauge / histogram)。
- Envoy Proxy v1.39.0,Access logging(format / command operators;HCM 挂载)。
- Envoy Proxy v1.39.0,Tracing(采样入口、header 传播、sidecar vs gateway span 模式)。
- Envoy Proxy v1.39.0,Administration
interface(
/stats、/stats?format=prometheus、flush 语义)。 - Envoy Proxy v1.39.0,HTTP
connection manager → Statistics(含
http.<stat_prefix>.tracing.*)。
站内对照
实验台账
- 本篇无本机
/stats粘贴;命令语义以 v1.39.0 admin 文档为准。
七、小结
- Stats / access log / tracing 都耦合在请求路径上,分别擅长聚合告警、单请求失败分类、跨跳相关。
- Admin 统计树按 listener / http / cluster / server 前缀读,先缩小层再下钻。
- ACK 配置 ≠ 观测已解释根因;warming、证书与池耗尽要回到机制篇与第 15 篇清单。
- 可观测性系列是姊妹,本篇只交 Envoy 数据面落点,不重写支柱与 SLO。
- 下一步:用第 15 篇清单把
RESPONSE_FLAGS/cluster.*/config_dump串成发布门禁,而不是只加一张「Envoy 5xx」面板。
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Envoy 数据面】生产排障:五条坐标系上的失败清单
按第 1 篇五条坐标系拆解无上游、路由未生效、证书/SDS、warming 黑洞、hot restart 与连接泄漏;给出 admin 核对顺序与观测信号入口,不虚构延迟数字。
【Envoy 数据面】选型收束:机制排除树与系列开放问题
用机制排除树收束 Envoy 相对 Nginx/HAProxy、sidecar / 节点级 Envoy / eBPF 的选型;回顾阅读路径,并列出 xDS 规模、sidecar 税、Wasm 与 HTTP/3 等系列级开放问题。
【Envoy 数据面】数据面全景:从 Listener 到 xDS 的可编程代理内核
定位 Envoy 相对 Nginx/HAProxy 静态配置代理与 Mesh 选型叙事的生态位;钉住请求路径、配置快照、FilterChainMatch、xDS warming、上游资源五条坐标系,并给出与 network/57 的分工及 16 篇阅读路线。
【Envoy 数据面】Main / Worker 与配置快照:事件循环、TLS 与几乎无锁热路径
钉住 Envoy 单进程多线程模型:Main 管 xDS/Admin,Worker 绑连接终生;Event::Dispatcher 与 Thread Local Storage 如何把配置变成每线程可读快照,以及快照解决什么、解决不了什么。