Envoy Listener 统计指标全解:从连接、TLS 到 QUIC 与 Listener Manager 的观测体系
【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy
本文系统梳理 Envoy 中 Listener 层的全部统计指标体系,涵盖通用连接指标、TLS 握手与证书指标、TCP/UDP/QUIC 传输指标、按工作线程(per-handler)拆分的连接指标以及 Listener Manager 生命周期指标,并给出指标树命名规则、源码实现位置与集成测试验证方式,帮助你在生产环境中完整构建针对接入层的可观测性与容量排障能力。
统计指标树的整体结构
Envoy 的 Listener 指标遵循统一的作用域(scope)命名规则:每个 listener 拥有一棵以listener.<address>.*为根的指标树。如果该 listener 配置了stat_prefix字段(即envoy.config.listener.v3.Listener.stat_prefix,定义见 listener.proto),则指标树根改为listener.<stat_prefix>.*。这一设计使得多环境共享同一监听地址时,可以通过stat_prefix将不同业务流量的指标区分开。
各子树的前缀规则如下:
| 指标类别 | 指标树前缀 |
|---|---|
| 通用连接指标 | listener.<address>.* |
| TLS 握手与证书验证 | listener.<address>.ssl.* |
| TLS/CA 证书有效期 | listener.<address>.ssl.certificate.<cert_name>. |
| TCP 传输段统计 | listener.<address>.tcp_stats.* |
| UDP 数据报统计 | listener.<address>.udp.* |
| QUIC 连接统计 | listener.<address>.quic_stats.* |
| 按 handler(线程)拆分 | listener.<address>.<handler>.* |
| Listener Manager 生命周期 | listener_manager.* |
Listener 通用连接指标
每个 listener 都具备以下通用指标(根前缀为listener.<address>.*):
| 名称 | 类型 | 说明 |
|---|---|---|
downstream_cx_total | Counter | 总连接数 |
downstream_cx_destroy | Counter | 已销毁连接总数 |
downstream_cx_active | Gauge | 当前活跃连接数 |
downstream_cx_length_ms | Histogram | 连接时长(毫秒) |
downstream_cx_transport_socket_connect_timeout | Counter | 在传输 socket 连接协商阶段超时的连接总数 |
downstream_cx_overflow | Counter | 因达到 listener 连接数上限而被拒绝的连接总数 |
downstream_cx_overload_reject | Counter | 因配置的过载动作(overload actions)被拒绝的连接总数 |
downstream_global_cx_overflow | Counter | 因达到全局连接数上限被拒绝的连接总数 |
connections_accepted_per_socket_event | Histogram | 每次 listener socket 事件接受的连接数 |
downstream_pre_cx_timeout | Counter | 在 listener filter 处理阶段超时的 socket 数 |
downstream_pre_cx_active | Gauge | 当前正在进行 listener filter 处理的 socket 数 |
extension_config_missing | Counter | 因缺失 listener filter 扩展配置而关闭的连接总数 |
network_extension_config_missing | Counter | 因缺失网络 filter 扩展配置而关闭的连接总数 |
no_filter_chain_match | Counter | 未匹配到任何 filter chain 的连接总数 |
downstream_listener_filter_remote_close | Counter | listener filter 窥视(peek)数据时被远端关闭的连接总数 |
downstream_listener_filter_error | Counter | listener filter 窥视数据时发生读取错误的总次数 |
这些指标覆盖了连接生命周期的完整漏斗:accept(downstream_cx_total)→ listener filter 处理(downstream_pre_cx_*)→ filter chain 匹配(no_filter_chain_match)→ 连接协商(downstream_cx_transport_socket_connect_timeout)→ 销毁(downstream_cx_destroy)。当出现连接被拒时,可通过downstream_cx_overflow(单 listener 限流)、downstream_global_cx_overflow(全局限流)与downstream_cx_overload_reject(过载管理动作)三个指标快速定位是哪种保护机制生效。
源码实现:ALL_LISTENER_STATS 宏
上述指标在源码中由 source/server/listener_stats.h 中的ALL_LISTENER_STATS宏统一定义,通过 X-Macro 模式同时展开为ListenerStats结构体成员。各指标在 source/server/active_listener_base.h 的ActiveListenerImplBase构造时创建,并挂到 listener 的 scope 上:
ActiveListenerImplBase(Network::ConnectionHandler& parent, Network::ListenerConfig* config) : stats_({ALL_LISTENER_STATS(POOL_COUNTER(config->listenerScope()), POOL_GAUGE(config->listenerScope()), POOL_HISTOGRAM(config->listenerScope()))}), per_worker_stats_({ALL_PER_HANDLER_LISTENER_STATS( POOL_COUNTER_PREFIX(config->listenerScope(), parent.statPrefix()), POOL_GAUGE_PREFIX(config->listenerScope(), parent.statPrefix()))}), config_(config) {}两个细节值得注意:
downstream_cx_active与downstream_pre_cx_active的 Gauge 均声明为Accumulate模式——即多 worker 线程各自的局部值会被累加,最终呈现为跨线程的总活跃数;- per-worker 指标通过
parent.statPrefix()添加前缀,这正是下节<handler>前缀的来源。
扩展配置缺失指标的触发路径
extension_config_missing与network_extension_config_missing两个计数器用于在基于扩展发现(EDS/NEDS/LDS 扩展下发)场景中检测"配置尚未就绪"的连接损失。从源码看,二者均在 source/common/listener_manager/listener_impl.cc 的扩展配置查找失败路径上inc(),并在 listener_impl.h 中以MissingListenerConfigStats结构统一声明。集成测试 test/integration/listener_extension_discovery_integration_test.cc 验证了:当扩展配置缺失时连接被拒、计数器从 0 递增,配置补齐后再次收数计数继续累加;test/integration/network_extension_discovery_integration_test.cc 对网络扩展缺失做了同类断言。
TLS 统计指标
当 listener 的 filter chain 启用 TLS(downstream TLS context)后,会出现根前缀为listener.<address>.ssl.*的 TLS 指标:
| 名称 | 类型 | 说明 |
|---|---|---|
connection_error | Counter | TLS 连接错误总数(不含证书验证失败) |
handshake | Counter | TLS 握手成功总数 |
session_reused | Counter | TLS 会话复用(resumption)成功总数 |
no_certificate | Counter | 未携带客户端证书即完成握手的连接总数 |
fail_verify_no_cert | Counter | 因缺少客户端证书导致验证失败总数 |
fail_verify_error | Counter | CA 验证失败的连接总数 |
fail_verify_san | Counter | SAN 验证失败的连接总数 |
fail_verify_cert_hash | Counter | 证书固定(pinning)验证失败的连接总数 |
ocsp_staple_failed | Counter | 因 OCSP 策略合规失败而终止的连接总数 |
ocsp_staple_omitted | Counter | 未附带 OCSP 响应但连接成功总数 |
ocsp_staple_responses | Counter | 有可用有效 OCSP 响应的连接总数(无论客户端是否请求) |
ocsp_staple_requests | Counter | 客户端请求 OCSP staple 的连接总数 |
ciphers.<cipher> | Counter | 使用指定密码套件完成握手的连接总数 |
curves.<curve> | Counter | 使用指定 ECDHE 曲线完成握手的连接总数 |
sigalgs.<sigalg> | Counter | 使用指定签名算法完成握手的连接总数 |
versions.<version> | Counter | 使用指定 TLS 协议版本完成握手的连接总数 |
其中ciphers.*、curves.*、sigalgs.*、versions.*是动态键指标(dynamically named stats),键值由实际握手结果决定,因此监控时需要用通配符聚合。session_reused / handshake的比值可以直接反映 TLS 会话复用率,是衡量握手开销优化的核心比例指标。
TLS 与 CA 证书统计
对每一张已加载的证书,还会在listener.<address>.ssl.certificate.<cert_name>.下暴露证书级别指标(见 cert_stats.rst):
| 名称 | 类型 | 说明 |
|---|---|---|
expiration_unix_time_seconds | Gauge | 证书到期时间距 UNIX 纪元的秒数 |
这是一个 Gauge 而非 Counter:它的值就是证书过期的 Unix 时间戳,因此可以直接与"当前时间"比较来驱动证书到期告警(例如now + 7d < expiration_unix_time_seconds时触发换证流程),无需解析文件系统。
TCP 传输段统计
当 listener 使用 TCP stats transport socket 时,会在listener.<address>.tcp_stats.*下暴露操作系统提供的 TCP 传输层指标(见 tcp_stats.rst):
| 名称 | 类型 | 说明 |
|---|---|---|
cx_tx_segments | Counter | 发送的 TCP 段总数 |
cx_rx_segments | Counter | 接收的 TCP 段总数 |
cx_tx_data_segments | Counter | 携带非零数据负载发送的 TCP 段总数 |
cx_rx_data_segments | Counter | 携带非零数据负载接收的 TCP 段总数 |
cx_tx_retransmitted_segments | Counter | 重传的 TCP 段总数 |
cx_rx_bytes_received | Counter | 已接收并已被 TCP 确认的载荷字节数 |
cx_tx_bytes_sent | Counter | 已发送的载荷字节数(含重传字节) |
cx_tx_unsent_bytes | Gauge | Envoy 已交给操作系统但尚未发出的字节数 |
cx_tx_unacked_segments | Gauge | 已发出但尚未被确认的段数 |
cx_tx_percent_retransmitted_segments | Histogram | 单个连接上被重传的段占比 |
cx_rtt_us | Histogram | 平滑后的往返时延估计(微秒) |
cx_rtt_variance_us | Histogram | 往返时延的方差估计(微秒),值越高抖动越大 |
官方文档特别注明:这些指标由操作系统提供,由于各操作系统(及同一系统的不同版本)可用指标与采样方式存在差异,数值可能跨平台不一致。因此它们适合用于趋势对比(同机、同版本)与重传/RTT 恶化告警,不适合跨环境横向绝对值比较。典型排障组合是:cx_rtt_us突增 +cx_tx_percent_retransmitted_segments升高 +cx_tx_unacked_segments堆积,通常指向下游网络链路劣化。
UDP 统计指标
UDP listener 在listener.<address>.udp.*下提供数据报级别指标:
| 名称 | 类型 | 说明 |
|---|---|---|
downstream_rx_datagram_dropped | Counter | 因内核缓冲区溢出或报文截断而丢弃的数据报数量 |
该指标是 QUIC/UDP 接入侧丢包的直接信号:由于 UDP 不保证交付,downstream_rx_datagram_dropped持续增长说明内核接收队列过载(例如 socket buffer 过小或应用侧读取不及时),应结合内核netstat -su的RcvbufErrors/InErrors交叉验证。
QUIC 统计指标
当使用 QUIC stats debug visitor 时,QUIC 连接指标会暴露在listener.<address>.quic_stats.*下:
| 名称 | 类型 | 说明 |
|---|---|---|
cx_tx_packets_total | Counter | 发送报文总数 |
cx_tx_packets_retransmitted_total | Counter | 重传报文总数 |
cx_tx_amplification_throttling_total | Counter | 服务端握手响应阶段被拥塞放大限制(amplification limiting)节流抑制的报文数。该值偏高通常意味着 TLS 证书链过长,一次往返无法完整发送 |
cx_rx_packets_total | Counter | 接收报文总数 |
cx_path_degrading_total | Counter | 检测到网络路径退化(path degrading)的次数 |
cx_forward_progress_after_path_degrading_total | Counter | 路径退化后仍取得前向进展的次数 |
cx_rtt_us | Histogram | 平滑后的往返时延估计(微秒) |
cx_tx_estimated_bandwidth | Histogram | 连接带宽估计值(字节/秒) |
cx_tx_percent_retransmitted_packets | Histogram | 连接上被重传的报文占比 |
cx_tx_mtu | Histogram | 该连接实际使用的最大报文大小 |
cx_rx_mtu | Histogram | 从对端接收到的最大报文大小 |
两个值得关注的诊断指标:cx_tx_amplification_throttling_total是 QUIC 服务端放大保护机制生效的次数,若持续非零,最常见的原因是证书链(含 OCSP staple)过大,优化方向是精简证书链;cx_path_degrading_total与cx_forward_progress_after_path_degrading_total的比值则刻画了连接在路径劣化后自愈的比例。
Per-handler(按线程)Listener 统计
除聚合指标外,每个 listener 还在listener.<address>.<handler>.*下暴露按 handler 拆分的指标,<handler>取值与 Envoy 线程模型对应:主线程为main_thread,各工作线程为worker_0、worker_1等,工作线程数量由--concurrency启动参数控制。这组指标由 source/server/listener_stats.h 中的ALL_PER_HANDLER_LISTENER_STATS宏定义:
| 名称 | 类型 | 说明 |
|---|---|---|
downstream_cx_total | Counter | 该 handler 上的总连接数 |
downstream_cx_active | Gauge | 该 handler 上的当前活跃连接数 |
其主要用途是发现 per-handler / per-worker 的连接不均衡:如果worker_3.downstream_cx_active显著高于其他 worker,说明连接在内核 accept 队列到各 worker 的分配上出现了倾斜(例如某个 worker 处理了更多 socket event),可用于排查线程级热点。前缀的生成逻辑见 source/server/active_listener_base.h:per-worker 指标以parent.statPrefix()(即 handler 名)为前缀挂在 listener scope 下。
Listener Manager 统计指标
Listener Manager 负责 listener 的动态增删与向 worker 分发,其指标根前缀为listener_manager.*,且指标名中的:会被替换为_。完整清单如下:
| 名称 | 类型 | 说明 |
|---|---|---|
listener_added | Counter | 新增 listener 总数(静态配置或 LDS) |
listener_modified | Counter | 通过 LDS 修改的 listener 总数 |
listener_removed | Counter | 通过 LDS 移除的 listener 总数 |
listener_stopped | Counter | 停止的 listener 总数 |
listener_create_success | Counter | 成功加入 worker 的 listener 对象总数 |
listener_create_failure | Counter | 加入 worker 失败的 listener 对象总数 |
listener_in_place_updated | Counter | 走 filter chain 就地更新(in-place update)路径创建的 listener 对象总数 |
total_filter_chains_draining | Gauge | 当前正在 draining 的 filter chain 数 |
total_listeners_warming | Gauge | 当前处于 warming 状态的 listener 数 |
total_listeners_active | Gauge | 当前活跃的 listener 数 |
total_listeners_draining | Gauge | 当前处于 draining 状态的 listener 数 |
workers_pinned | Gauge | 启用 worker CPU 亲和性时被绑定 CPU 的 worker 线程数,否则为 0 |
workers_started | Gauge | 布尔值(1/0),表示 listener 是否已在 worker 上完成初始化 |
这组指标是验证 LDS 动态下发是否落地的核心观测面:
listener_added/listener_modified增长而listener_create_failure同时增长,说明配置下发了但 listener 对象在 worker 上创建失败,应检查端口冲突与 filter 初始化错误;total_listeners_warming长时间不回落,通常意味着 warming 阶段(如订阅资源未就绪)卡住;listener_in_place_updated增长表示 Envoy 走的是 filter chain 就地热更新路径(而非整 listener 重建),可据此评估配置变更对存量连接的影响范围;workers_started保持为 0 说明 worker 尚未完成 listener 初始化,Envoy 还不接受流量,可用于部署就绪探针判断。
实践要点小结
- 指标定位路径:排障时按
listener_manager.*(配置是否下发)→listener.<address>.*(连接漏斗)→ssl.*/quic_stats.*/tcp_stats.*(传输层细节)的层级下钻,每一层都有独立的作用域前缀,便于在监控系统中做聚合与下钻。 - Gauge 的 Accumulate 语义:
downstream_cx_active、downstream_pre_cx_active等 Gauge 采用Accumulate模式聚合多 worker 局部值(见 source/server/listener_stats.h),因此它们是"总量"而非"每 worker 均值",容量告警可直接基于该值设定。 - 证书到期告警:直接对
ssl.certificate.<cert_name>.expiration_unix_time_seconds与当前时间比较即可实现证书到期监控,不依赖额外解析。 - UDP/QUIC 丢包定位:
downstream_rx_datagram_dropped(内核溢出/截断)与 QUIC 的cx_tx_percent_retransmitted_packets、cx_rtt_us组合使用,可以区分是接收侧资源不足还是链路质量问题。 - 平台差异注意:TCP stats 由操作系统提供,跨 OS 数值可能不一致,告警阈值应基于同平台基线设置。
以上全部指标的文档定义集中在 docs/root/configuration/listeners/stats.rst,TLS/证书/TCP 明细表分别位于 ssl_stats.rst、cert_stats.rst 与 tcp_stats.rst;指标实现见 source/server/listener_stats.h 与 source/server/active_listener_base.h,Listener Manager 侧实现见 source/common/listener_manager/listener_manager_impl.cc。
【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考