Envoy On-Demand 更新过滤器实战:按需 VHDS、S/RDS 与 CDS 动态配置详解 📅 发布时间:2026/9/13 13:28:20 👁 浏览次数: Envoy On-Demand 更新过滤器实战按需 VHDS、S/RDS 与 CDS 动态配置详解【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy本篇技术指南围绕 Envoy 的 on-demand 更新过滤器HTTP filterenvoy.filters.http.on_demand展开系统讲解如何在流量到达时才动态拉取 Virtual Host按需 VHDS、Scoped Route 对应的 Route Configuration按需 S/RDS以及缺失的 Cluster按需 CDS三类 xDS 资源适用于大规模控制平面下无法提前下发全量路由与集群配置的微服务网关场景。读完本文你将掌握该过滤器的触发条件、OnDemand/PerRouteConfig配置结构、按 Virtual Host/Route 粒度启停按需 CDS 的方法以及其底层基于requestRouteConfigUpdate与 ODCDS API 的实现机制。一、为什么需要按需更新过滤器在典型的 xDS 控制平面架构中Envoy 通常通过 CDS/RDS/VHDS/SRDS 提前拉取集群与路由配置。但当代理实例数量庞大、租户或服务数量众多时预先下发全量配置会带来明显的控制平面压力连接数多、内存占用高、首次配置下发慢。On-demand 更新过滤器解决的核心问题是让配置下发从提前全量变为流量驱动。当某个请求需要用到尚不存在的路由或集群时过滤器拦截该请求触发一次针对性的 xDS 拉取待资源就绪后恢复请求处理。它支持的三种按需能力如下按需能力请求的资源触发条件按需 VHDSVirtualHostroute.v3.VirtualHostRouteConfiguration 中启用vhds且请求携带Host或:authority头按需 S/RDSRouteConfigurationScoped Route 场景ScopedRouteConfiguration中设置on_demand: true且请求头能匹配出 scope按需 CDSODCDSCluster路由动作使用cluster_header指定集群名请求已到达但目标集群缺失且过滤器配置了odcds需要特别注意的是原文档明确指出按需 VHDS 与按需 S/RDS 目前不能同时使用On-demand VHDS and on-demand S/RDS can not be used at the same time at this point设计配置时需要在两种路由发现模式中二选一。二、过滤器配置基础类型 URL、位置与 API 版本在 docs/root/configuration/http/http_filters/on_demand_updates_filter.rst 中官方给出了三点硬性配置要求类型 URL 固定该过滤器必须使用类型 URLtype.googleapis.com/envoy.extensions.filters.http.on_demand.v3.OnDemand进行配置过滤器链位置必须放置在 HttpConnectionManager 过滤器链中envoy.filters.http.router过滤器之前。这是因为按需更新发生在路由解析router 过滤器负责执行之前先拦截、后放行两套配置对象全局扩展配置OnDemandv3 API 引用每路由/每虚拟主机配置PerRouteConfig。过滤器在源码中的注册名为envoy.filters.http.on_demand见 well_known_names.h。其工厂类OnDemandFilterFactory通过REGISTER_FACTORY静态注册并在createHttpFilterFactoryFromProtoTyped中构造配置、以addStreamDecoderFilter形式挂载到过滤器链见 config.cc。最简配置形如http_filters: - name: envoy.filters.http.on_demand typed_config: type: type.googleapis.com/envoy.extensions.filters.http.on_demand.v3.OnDemand - name: envoy.filters.http.router typed_config: type: type.googleapis.com/envoy.extensions.filters.http.router.v3.Router当OnDemand消息体为空即未设置odcds字段时过滤器退化为仅支持按需 RDS/VHDS的行为。这一行为在 on_demand_update.cc 的createDecodeHeadersBehavior中体现odcds_config不存在时直接返回DecodeHeadersBehavior::rds()。三、按需 VHDS用 Host / :authority 头驱动 Virtual Host 拉取3.1 触发条件与流程按需 VHDS 的场景是请求到达时目标VirtualHost尚未出现在本地 Route Configuration 中。此时过滤器读取请求的Host或:authority头以此为 key 发起 VHDS 请求。官方给出的两个前提缺一不可RouteConfiguration 中启用了vhds字段route.proto请求中必须存在Host或:authority头。配置示例bootstrap 中 http_connection_manager 的 route_configroute_config: name: route_config vhds: config_source: ads: {} resource_api_version: V3 virtual_hosts: []3.2 源码层面的执行链路按需 VHDS 的核心逻辑在OnDemandRouteUpdate::handleMissingRoute()on_demand_update.cc先通过callbacks_-route()尝试解析路由若解析成功设置迭代状态为FilterHeadersStatus::Continue直接放行若解析失败路由缺失将状态置为FilterHeadersStatus::StopIteration暂停请求并注册RouteConfigUpdatedCallback调用callbacks_-downstreamCallbacks()-requestRouteConfigUpdate(route_config_updated_callback_)发起一次按需路由更新。路由更新完成后由onRouteConfigUpdateCompletion(bool route_exists)on_demand_update.cc接管若更新成功且请求体已完整读完downstream_end_stream_尝试callbacks_-recreateStream()重建整个请求流因为重定向等场景要求完整读取请求体重建成功后请求会从头重新走一遍过滤器链若路由仍不存在或重建失败则调用callbacks_-continueDecoding()继续过滤器链由下游过滤器通常是 router决定如何响应如返回 404。此外过滤器在onDestroy()on_demand_update.cc中会重置route_config_updated_callback_与cluster_discovery_handle_确保当过滤器链已经关闭时已注册的回调不会被意外唤醒。四、按需 S/RDSScoped Route 场景下的延迟加载当使用 ScopedRouteConfiguration 将多条 Route Configuration 按 scope key 组织时可以让某些 scope 对应的 RouteConfiguration 按需加载。过滤器的角色是用请求头解析出 scope若该 scope 的 Route Configuration 尚未加载则触发按需拉取。4.1 配置要点在 scoped_route.proto 中ScopedRouteConfiguration新增了on_demand布尔字段scoped_routes: name: foo_scope scope_key_builder: fragments: - header_value_extractor: name: Addr element_separator: , element: key: x-foo-key index: 0 rds_config_source: ads: {} scoped_route_configurations_list: - name: foo_scope1 route_configuration_name: foo_route1 on_demand: true key: fragments: - string_key: foo当 scope 的on_demand为true且该 scope 的 Route Configuration 尚未加载时请求头示例中通过Addr头解析 scope key会触发一次针对性的 RDS 拉取。4.2 集成测试佐证on_demand_integration_test.cc 中的OnDemandUpdateSuccess测试完整还原了这一流程预置过滤器后先下发on_demand: true的 scope再发送一个携带Addr: x-foo-keyfoo头的请求Envoy 随即建立 RDS 流并拉取foo_route1最终返回 200。而OnDemandUpdateScopeNotMatch测试则验证了反面场景请求头无法匹配任何 scope 时即使配置了 on-demand 过滤器请求仍返回 404说明按需拉取只在确实需要时才发生。五、按需 CDSODCDScluster_header 驱动的集群发现5.1 适用场景当路由动作使用cluster_headerroute_components.proto时目标集群名来自请求头、只有在收到请求后才能确定。若该集群尚未通过常规 CDS 下发请求将无法处理。按需 CDS 正是为此设计请求到达时集群缺失 → 过滤器暂停请求 → 发起按需集群发现 → 发现结束无论成败后恢复请求。5.2 OnDemandCds 配置结构按需 CDS 通过 OnDemandCds 消息配置字段如下字段类型说明sourceconfig.core.v3.ConfigSource用于按需集群发现的服务配置源xDS 服务地址通常为 ADSresources_locatorstringxdstp://格式的按需集群集合资源定位符timeoutgoogle.protobuf.Duration按需集群查找超时时间未设置时默认 5 秒注意 proto 文件头部有一条重要 warningEnvoy 目前仅支持在增量 xDSIncremental-xDS模式下使用按需 CDS不支持 State-of-the-WorldSOTW模式部署控制平面时需保证走 Delta xDS。全局启用按需 CDShttp_filters: - name: envoy.filters.http.on_demand typed_config: type: type.googleapis.com/envoy.extensions.filters.http.on_demand.v3.OnDemand odcds: source: ads: {} resource_api_version: V3 timeout: 5s - name: envoy.filters.http.router typed_config: type: type.googleapis.com/envoy.extensions.filters.http.router.v3.Router使用xdstp://资源定位符指定按需集群集合与 odcds_integration_test.cc 中的用法一致odcds: resources_locator: xdstp://authority1.com/envoy.config.cluster.v3.Cluster/on_demand_clusters source: ads: {} timeout: 5s5.3 底层实现剖析在 on_demand_update.cc 的handleOnDemandCds中完整判断链路为若callbacks_-clusterInfo()已存在说明集群已在本地直接Continue不触发任何发现取route.routeEntry()若为空则继续取entry-clusterName()若为空典型原因是cluster_header指定的头缺失则继续否则置StopIteration通过odcds.requestOnDemandClusterDiscovery(cluster_name, callback, timeout)发起异步发现期间请求被暂停。发现完成后的处理在onClusterDiscoveryCompletionon_demand_update.cc中其行为受运行时标志envoy.reloadable_features.on_demand_cluster_no_recreate_stream控制标志开启默认路径集群可用时调用recreateClusterInfo()刷新集群信息随后一律continueDecoding()不再重建整个请求流标志关闭集群可用且请求体已完整读完时尝试recreateStream()重建请求流失败则continueDecoding()。无论发现成功与否请求最终都会被恢复继续处理若集群始终不存在则由后续过滤器链router产生相应错误响应。5.4 按需 CDS 的超时与失败处理createDecodeHeadersBehavior中通过PROTOBUF_GET_MS_OR_DEFAULT(odcds_config.ref(), timeout, 5000)读取超时值on_demand_update.cc默认 5000ms。odcds_integration_test.cc中的超时用例以 500ms 的超时验证了发现超时后请求继续、不会无限挂起的行为。六、按 Virtual Host / Route 粒度启停按需 CDS按需 CDS 不仅可以在过滤器层面全局启用还可以在 Virtual Host 或 Route 粒度覆盖。覆盖机制依托两个typed_per_filter_config字段Virtual Host 级VirtualHost.typed_per_filter_configRoute 级Route.typed_per_filter_config。规则非常明确原文档原话逻辑在 Virtual Host 或 Route 的typed_per_filter_config中为envoy.filters.http.on_demand指定了扩展配置但未包含odcds字段→ 该 Virtual Host / Route 上禁用按需 CDS指定了配置且包含odcds字段→ 该 Virtual Host / Route 上启用按需 CDS。启用示例Route 级配合cluster_header使用routes: - match: { prefix: / } route: cluster_header: x-envoy-upstream-cluster typed_per_filter_config: envoy.filters.http.on_demand: type: type.googleapis.com/envoy.extensions.filters.http.on_demand.v3.PerRouteConfig odcds: source: ads: {} timeout: 5s禁用示例Virtual Host 级配置类型但省略odcdsvirtual_hosts: - name: backend domains: [*] typed_per_filter_config: envoy.filters.http.on_demand: type: type.googleapis.com/envoy.extensions.filters.http.on_demand.v3.PerRouteConfig routes: - match: { prefix: / } route: { cluster: backend }从源码看PerRouteConfig 与OnDemand共享相同的odcds字段结构且在 config.cc 中通过createRouteSpecificFilterConfigTyped生成路由级配置。配置解析时createDecodeHeadersBehavior的判空逻辑无odcds→ 退化为仅 RDS 行为正是省略odcds即禁用按需 CDS的实现基础。优先级方面OnDemandRouteUpdate::getConfig()on_demand_update.h会先尝试resolveMostSpecificPerFilterConfig解析最具体的per-route 配置Route 优先于 Virtual Host找不到时才回退到过滤器全局配置。七、组合使用、限制与最佳实践7.1 能力组合关系从DecodeHeadersBehavior的两种实现on_demand_update.cc可以看清组合边界rds()仅做路由/虚拟主机按需发现对应无odcds配置cdsRds(odcds, timeout)先做路由发现路由成功后再做按需集群发现对应配置了odcds。后者的执行顺序在RdsCdsDecodeHeadersBehavior::decodeHeaders中明确为先handleMissingRoute()路由解析成功后才调用handleOnDemandCds()。7.2 使用限制清单综合原文档与 on_demand.proto 中的声明使用本过滤器前必须确认以下约束按需 VHDS 与按需 S/RDS 互斥同一部署只能启用其一按需 CDS 仅支持增量 xDSDelta xDSSOTW 模式不适用过滤器必须位于envoy.filters.http.router之前按需 VHDS 需要请求携带Host或:authority头按需 CDS 需要路由动作配置cluster_header且请求携带对应头头缺失时集群名为空无法触发发现按需集群查找默认超时 5 秒可通过timeout调整。7.3 配置核对清单http_filters中envoy.filters.http.on_demand是否在envoy.filters.http.router之前使用按需 VHDS 时route_config.vhds.config_source是否已指向 ADS 或独立 xDS使用按需 S/RDS 时对应的ScopedRouteConfiguration.on_demand是否设为true使用按需 CDS 时控制平面是否支持 Delta xDSodcds.source/resources_locator/timeout是否正确需要在某个 VH/Route 上禁用按需 CDS 时是否在该粒度的typed_per_filter_config中配置了不带odcds字段的PerRouteConfig八、源码与测试索引官方文档docs/root/configuration/http/http_filters/on_demand_updates_filter.rst扩展配置 protoapi/envoy/extensions/filters/http/on_demand/v3/on_demand.protoOnDemand、OnDemandCds、PerRouteConfig过滤器实现source/extensions/filters/http/on_demand/on_demand_update.cc、on_demand_update.h工厂注册source/extensions/filters/http/on_demand/config.cc按需 S/RDS 集成测试test/extensions/filters/http/on_demand/on_demand_integration_test.cc按需 CDS 集成测试含超时、xdstp 场景test/extensions/filters/http/on_demand/odcds_integration_test.cc配置工厂单测test/extensions/filters/http/on_demand/config_test.cc关联路由 APIapi/envoy/config/route/v3/route.protovhds、VirtualHost.typed_per_filter_config、route_components.protocluster_header、Route.typed_per_filter_config、scoped_route.protoon_demand【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考