ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Envoy Dynamic Forward Proxy DNS 缓存统计的 Server Scope 变更:从监听器级到全局 Stats Matcher

2026/9/12 16:47:59 拓冰建站 浏览量
Envoy Dynamic Forward Proxy DNS 缓存统计的 Server Scope 变更:从监听器级到全局 Stats Matcher Envoy Dynamic Forward Proxy DNS 缓存统计的 Server Scope 变更从监听器级到全局 Stats Matcher【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy导读本篇围绕 Envoy 动态转发代理Dynamic Forward ProxyDNS 缓存的统计指标dns_cache.*作用域变更展开说明这些指标如何从首次实例化 manager 单例时由调用方派生的 scope迁移到服务器级server-widestats scope以及由此带来的统计匹配规则变化。读完本文你将理解dns_cache.*指标的创建路径、为何统计匹配从 per-listener 变为全局、受影响的配置场景以及如何用 bootstrap 级stats_matcher对 DNS 缓存统计进行精确过滤。本文对应的变更记录为 dynamic_forward_proxy__dns-cache-stats-server-scope.rst属于 minor behavior change即统计指标名称与含义不变但指标在统计树中的挂载位置与匹配规则发生改变。变更核心DNS 缓存统计统一挂载到 Server 级 Stats Scope变更前行为在本次变更之前DNS 缓存统计dns_cache.*创建在manager 单例首次被实例化时由调用方caller派生的 scope之下。由于 DnsCacheManager 是进程级单例见下文其首次实例化的调用方往往来自某个具体的 listener 或 filter 上下文因此统计 scope 会继承该调用方的 per-listener stats matcher。这带来的问题在于同一个 DNS 缓存可能被多个 listener 引用但它的统计却只受第一个创建它的 listener所声明的 stats matcher 约束。如果该 listener 配置了局部per-listenerstats matcher而其它引用同一缓存的 listener 没有配置就会出现统计匹配行为不一致、甚至统计被意外过滤或保留的情况。变更后行为变更后DNS 缓存统计始终创建在服务器级server-widestats scope之下不再依赖调用方。因此dns_cache.*统计统一匹配 bootstrap 中配置的全局stats_matcher对应字段config.metrics.v3.StatsConfig.stats_matcher不再受任何 per-listener stats matcher 影响统计名称statistic names保持不变即dns_cache.cache_name.stat的命名规则没有变化。从源码结构看这一改动在 dns_cache_impl.cc 的构造函数中体现得非常直接scope_(server_context.serverScope().createScope(fmt::format(dns_cache.{}., config.name()))), stats_(generateDnsCacheStats(*scope_)), resource_manager_(*scope_, server_context.runtime(), config.name(), config.dns_cache_circuit_breaker()),关键点在于server_context.serverScope()这里显式从ServerFactoryContext的服务器级 scope 派生子 scopedns_cache.cache_name.而不是从某个 listener/filter 的 scope 派生。也就是说无论哪个 listener 最先触发 DNS 缓存创建统计始终挂在服务器根 scope 之下。源码级佐证单例 manager 与 scope 的创建路径DnsCacheManager 是进程级单例DnsCacheManager 通过SINGLETON_MANAGER_REGISTRATION注册为单例见 dns_cache_manager_impl.ccSINGLETON_MANAGER_REGISTRATION(dns_cache_manager); DnsCacheManagerSharedPtr DnsCacheManagerFactoryImpl::get() { return server_context_.singletonManager().getTypedDnsCacheManager( SINGLETON_MANAGER_REGISTERED_NAME(dns_cache_manager), [this] { return std::make_sharedDnsCacheManagerImpl(server_context_); }); }单例的性质决定了首次实例化只发生一次第一个引用 DNS 缓存的 listener/filter 会触发 manager 及其缓存对象的创建后续引用方复用同一实例。在旧实现中scope 若由调用方派生则后续引用方只能被动接受首次调用方决定的 scope而新实现统一使用serverScope()彻底消除了这一不确定性。缓存按 name 复用配置必须一致在 dns_cache_manager_impl.cc 中getCache()按config.name()查找已有缓存若已存在同名缓存且新配置与原配置不等价通过MessageDifferencer::Equivalent比较直接返回错误config specified DNS cache {} with different settings否则创建新的DnsCacheImpl并存入caches_。这说明DnsCacheConfig.name见 dns_cache.proto是缓存的唯一标识多个组件可以引用同一个命名缓存但配置必须完全相同。结合本变更同一命名缓存的统计也必然只有一份且统一受全局 stats matcher 约束。完整的 DNS 缓存统计指标清单DNS 缓存统计由 dns_cache_impl.h 中的ALL_DNS_CACHE_STATS宏定义并通过generateDnsCacheStatsdns_cache_impl.cc在创建的 scope 下注册类型指标名含义从命名与使用场景推断Countercache_load缓存从持久化 KeyValueStore 加载条目的次数Counterdns_address_filter_out被resolved_address_filter地址过滤器过滤掉的解析结果数Counterdns_query_attemptDNS 查询尝试次数Counterdns_query_failureDNS 查询失败次数Counterdns_query_successDNS 查询成功次数Counterdns_query_timeoutDNS 查询超时次数Counterhost_added缓存中新增主机条目的次数Counterhost_address_changed主机解析地址发生变化的次数Counterhost_overflow主机数超过max_hosts上限被拒绝的次数Counterhost_removed缓存中移除主机条目的次数Counterdns_rq_pending_overflow待处理 DNS 请求超过熔断上限的次数Gaugenum_hostsNeverImport缓存中当前主机数量所有指标的完整名称形如dns_cache.cache_name.stat其中cache_name来自DnsCacheConfig.name。除上述统计外同一 scope 下还会注册 DNS 缓存熔断器circuit breaker相关统计见 dns_cache_resource_manager.cc其中ALL_DNS_CACHE_CIRCUIT_BREAKERS_STATS使用stat_prefix生成熔断器 gauge默认上限为 1024 个待处理请求可在DnsCacheCircuitBreakers.max_pending_requests中覆盖见 dns_cache.proto。对配置的影响哪些场景会感知到变化受影响场景原文档明确指出本次变更只影响一类配置首次创建 DNS 缓存的 listener 声明了 per-listener stats matcher的情况。具体而言多个 listener / filter 通过同名DnsCacheConfig共享同一个 DNS 缓存其中最先触发缓存创建的 listener 配置了 per-listenerstats_matcher变更前dns_cache.*统计可能被该 listener 的局部匹配规则过滤掉或命中变更后该局部规则不再生效统计改由 bootstrap 的全局stats_matcher决定。不受影响的场景统计名称不变dns_cache.cache_name.stat的命名、含义、Counter/Gauge 类型均无变化依赖这些指标名的监控告警无需修改未配置 per-listener stats matcher 的部署统计挂载位置虽然物理上变为 server scope但对可观测结果无实际差异依赖serverScope()派生子 scope 的其它组件行为不变。实战用全局 stats matcher 过滤 DNS 缓存统计1. 在 bootstrap 中配置全局 stats matcher变更后过滤dns_cache.*的正确位置是 bootstrap 的stats_config.stats_matcher全局字段对应config.metrics.v3.StatsConfig.stats_matcher。以下示例将前缀为dns_cache.的统计全部排除stats_config: stats_matcher: exclusion_list: patterns: - prefix: dns_cache.配置后所有dns_cache.*指标包括各缓存的 Counter/Gauge将不再被创建。该行为已由仓库测试 dns_cache_manager_impl_test.cc 中的GlobalStatsMatcherFiltersDnsCacheStats用例覆盖验证测试构造 store 级bootstrapStatsMatcher以dns_cache.前缀加入排除列表后dns_cache.cache_a.dns_query_attempt无法被找到而排除列表外的kept指标仍然正常创建。从测试代码可见该用例刻意将 server scope 路由到生产风格的 store// Route the server scope to the production-like store so stats behavior (including // StatsMatcher handling) matches the real deployment. ON_CALL(server_context_, serverScope()).WillByDefault(ReturnRef(*store_.rootScope()));这正是本次行为变更在测试层面最直接的印证server scope 的 stats matcher 决定了 DNS 缓存统计的存亡。2. 精细过滤单个缓存若只想排除特定缓存例如cache_a可将前缀改为更精确的值stats_config: stats_matcher: exclusion_list: patterns: - prefix: dns_cache.cache_a.3. 确认统计是否生效在 admin 接口查看统计默认路径GET /stats或GET /stats?filterdns_cache。变更后只要 bootstrap 的全局 stats matcher 未排除dns_cache.前缀即可看到形如dns_cache.cache_a.dns_query_attempt: 42 dns_cache.cache_a.dns_query_success: 38 dns_cache.cache_a.dns_query_failure: 3 dns_cache.cache_a.num_hosts: 17注意不要再依赖 per-listener stats matcher 来过滤dns_cache.*——该方式在本次变更后已不再生效。排查与升级建议升级前检查如果你的部署在 bootstrap 之外还依赖某 listener 的 per-listener stats matcher 过滤dns_cache.*升级到包含本变更的版本后这些指标将重新出现受全局规则管辖。请据此评估统计量对 admin 接口 / 指标采集端的影响必要时在 bootstrap 全局stats_matcher中显式排除。统一在全局配置统计策略由于dns_cache.*的 scope 已固定为 server 级统计过滤策略应当收敛到stats_config.stats_matcher一处避免在多处重复声明造成歧义。监控告警无需改动指标名与语义不变既有的基于dns_cache.*的告警与面板可以继续使用。同名缓存配置一致性多个组件引用同名 DNS 缓存时配置必须完全一致源码会在不匹配时直接报错统计也只有一份规划缓存命名时建议让缓存名与业务用途对应便于后续按前缀过滤与聚合。总结本次 minor behavior change 的本质是统计作用域的去调用方化dns_cache.*统计从由首次实例化 manager 单例的调用方派生 scope改为始终挂载于serverScope()派生的子 scope从而统一接受全局stats_matcher管辖。对绝大多数部署而言这只是内部实现细节的调整但对那些首个创建 DNS 缓存的 listener 配置了 per-listener stats matcher的部署升级后需要将统计过滤逻辑迁移到 bootstrap 全局stats_config.stats_matcher中。指标名称、含义与类型均保持不变监控体系无需改动即可平滑过渡。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考