ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Envoy VHDS(虚拟主机发现服务)深度解析:基于 Delta xDS 的按需 Virtual Host 订阅机制

Envoy VHDS(虚拟主机发现服务)深度解析:基于 Delta xDS 的按需 Virtual Host 订阅机制 Envoy VHDS虚拟主机发现服务深度解析基于 Delta xDS 的按需 Virtual Host 订阅机制【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy导读Virtual Host Discovery ServiceVHDS虚拟主机发现服务是 Envoy 提供的一个可选 xDS 扩展 API它让路由配置RouteConfiguration不再一次性全量下发所有虚拟主机而是由每个 Envoy 实例按需订阅自身实际需要的 VirtualHost。本篇文章以 docs/root/configuration/http/http_conn_man/vhds.rst 为主线结合仓库内路由模块的真实源码实现与测试用例系统讲解 VHDS 的诞生背景、资源命名规范、基于 Delta xDS 的订阅/退订协议流程、更新语义、与 Scoped RDS 的兼容性以及统计指标帮助你在大规模网格场景下正确理解并落地 VHDS。一、为什么需要 VHDSRDS 全量下发带来的扩展性问题在默认的 RDSRoute Discovery Service模式下一个集群cluster的全部路由规则会被发送给网格中的每一个Envoy 实例。随着集群规模增长这种全量广播机制会产生明显的扩展问题每个代理都需要接收、解析并缓存与自身无关的海量路由配置路由配置的复杂度绝大多数集中在 VirtualHost虚拟主机上而单个代理真正用到的 VirtualHost 往往只是其中一小部分配置下发链路成为瓶颈任何一次路由变更都意味着所有实例的全量更新。VHDS 正是针对这一痛点而设计它使用Delta xDS增量 xDS协议让路由配置先被订阅之后只按需请求实际需要的 VirtualHost。相比一个路由配置携带全部 VirtualHost的传统方式VHDS 允许 Envoy 实例从 xDS 管理服务器内部维护的虚拟主机列表中动态订阅与退订管理服务器会持续监控这份订阅列表并据此过滤下发给单个 Envoy 实例的配置使其只包含该实例真正订阅的 VirtualHost。换句话说RDS 解决路由配置如何分发的问题而 VHDS 解决路由配置中哪些 VirtualHost 才需要真正下发的问题。二、Virtual Host 资源命名规范在 VHDS 中每个 VirtualHost 资源由两部分联合标识它所属的路由配置名称route configuration name传入请求的 HTTPhost头HTTP/2 下为:authority条目。资源名称的格式如下route configuration name/host entry例如路由配置名为my_route_config、host 为www.example.com则对应的 VHDS 资源名就是my_route_config/www.example.com需要特别注意匹配方向由于host 条目中不能包含斜杠/而路由配置名可以包含斜杠因此对资源名称的解析/匹配必须从右往左进行——从右侧第一个/切分出 host 条目剩余部分才是路由配置名称。这一约定保证了即使路由配置名里出现斜杠也不会产生歧义。三、资源订阅机制Delta xDS 下的按需请求3.1 订阅请求的协议形态VHDS 的资源订阅通过 DeltaDiscoveryRequest 消息完成关键字段如下type_url固定为type.googleapis.com/envoy.config.route.v3.VirtualHostresource_names_subscribe填入该实例希望获取配置的 VirtualHost 资源名列表遵循第二节的命名规范。关于 Delta xDS 的订阅语义xDS 协议文档 中明确客户端可以在resource_names_subscribe字段中发送资源的alias别名或名称服务端在判断某个资源是否已被订阅时应同时检查资源名与别名。此外即使服务端认为客户端已订阅且持有最新版本响应中仍必须重新下发这些资源——因为客户端可能由于内部实现细节遗忘了它们。3.2 路由未命中时的暂停—请求—恢复流程当某个请求的 host/authority 头在当前缓存的路由配置中无法解析到对应路由时Envoy 会采取如下动作暂停当前活跃流active stream 被 pause避免在配置缺失的情况下做出错误路由决策发送一条DeltaDiscoveryRequest将所需的 VirtualHost 资源名放入resource_names_subscribe等待管理服务器返回DeltaDiscoveryResponse当响应中某个资源的aliases字段或name字段与请求中的resource_names_subscribe条目精确匹配时路由配置被更新、被暂停的流恢复filter chain 继续处理。值得强调的是匹配条件同时覆盖aliases与name这意味着管理服务器既可以按正式资源名响应也可以按别名响应Envoy 均能正确识别该行为与 xDS 协议文档 中名称与别名都应检查的约定一致。如果管理服务器无法解析某个别名它会在响应中返回一个空的资源条目不包含 VirtualHost 内容这一点在 vhds.cc 的onConfigUpdate实现中有直接体现。3.3 退订Unsubscribe与订阅对称当 Envoy 对某些 VirtualHost 失去兴趣时通过DeltaDiscoveryRequest.resource_names_unsubscribe字段退订可填资源名或别名。服务端甚至可能收到它认为客户端本来就未订阅的多余退订请求phantom unsubscription也必须干净地处理、直接忽略不需要强制回送removed_resources响应——除非客户端同时持有通配符订阅*此时服务端必须明确回应该资源的归属详见 xDS 协议文档。四、更新语义RDS 与 VHDS 各司其职VirtualHost 的更新遵循一条清晰的归属原则来源更新通道最初通过 RDS 下发的 VirtualHost仍通过RDS更新通过 VHDS 订阅获取的 VirtualHost通过VHDS更新这意味着一旦确定了某个 VirtualHost 的分发通道后续的变更就必须走同一条通道不能混用。从源码上看这条规则体现在 route_config_update_receiver_impl.cc 的onRdsUpdate与onVhdsUpdate两个回调中RDS 更新构建独立的rds_virtual_hosts_映射VHDS 更新维护独立的vhds_virtual_hosts_映射二者在生成最终路由配置时通过rebuildRouteConfigVirtualHosts合并先清空route_config.virtual_hosts再把 RDS 与 VHDS 两部分的 VirtualHost 依次合并写入。另一条关键的缓存语义当一条路由配置条目被更新且其中的vhds字段发生变化时该路由配置对应的 VirtualHost 表会被整体清空之后所有 VirtualHost 都必须重新下发。这一设计避免了新旧vhds配置源混用导致的状态错乱。五、与 Scoped RDS 的兼容性VHDS 与 Scoped RDSScopedRouteConfiguration 配合使用时不存在兼容性障碍路由配置名称仍可用于 VirtualHost 匹配在配置了 Scoped RDS 的情况下该名称指向的是 scoped route configuration特别提醒如果将on-demand按需Scoped RDS与 VHDS 同时使用则每个 routing scope 需要两次 on-demand 订阅一次订阅 scoped route configuration一次订阅其 VirtualHost这会带来额外的按需订阅开销规划容量时需要计入。六、在 RouteConfiguration 中启用 VHDS 配置VHDS 的配置入口位于 RouteConfiguration 消息 的vhds字段v3 API 中字段号为 9其消息结构定义如下见 route.proto 中的message Vhdsmessage Vhds { // Configuration source specifier for VHDS. core.v3.ConfigSource config_source 1 [(validate.rules).message {required: true}]; }config_source为必填项用于指定 VHDS 的配置来源。结合 vhds.cc 中createVhdsSubscription的校验逻辑config_source必须满足以下硬性约束之一否则订阅创建直接失败返回InvalidArgumentErrorDELTA_GRPC类型的 gRPC 配置源——VHDS 只支持 Delta xDS 语义ADS但存在两个前提条件bootstrap 中必须配置了dynamic_resources.ads_config该 ADS 配置的api_type必须是DELTA_GRPC即父 ADS 流本身运行在 Delta 模式下。也就是说VHDS 无法使用 SotWState of the World或 REST 等非 Delta 通道。示例配置形态route_configurations: - name: my_route_config vhds: config_source: api_config_source: api_type: DELTA_GRPC grpc_services: - envoy_grpc: cluster_name: my_xds_cluster virtual_hosts: []RouteConfiguration级别的其他路由字段如ignore_port_in_host_matching、vhost_header等不受 VHDS 影响VirtualHost 的匹配语义保持一致。七、统计指标VHDS 拥有一个以http.stat_prefix.vhds.virtual_host_name.为根的统计树。由于统计树名中不能包含:VirtualHost 名称中的任何:字符都会被替换为_。该统计树包含以下统计项名称类型描述config_reloadCounter因配置发生变化而触发配置重载的 API 拉取总次数empty_updateCounter收到的空更新empty update总次数从实现细节看vhds.h 中ALL_VHDS_STATS宏实际定义的计数器名为config_reload与update_empty后者对应文档所述的空更新计数注意源码标识符与文档描述的名称略有差异config_reload计数器在 vhds.cc 的onConfigUpdate中仅当receiver_.onVhdsUpdate(...)返回真即本次更新确实改动了配置时自增并伴随debug级日志输出loading new configuration: config_name... version...。另外从源码结构看vhds.cc 中统计作用域的实际组织方式是stat_prefix[rds.]vhds.route config name.经 RDS 下发的路由配置其 VHDS 订阅嵌套在该路由配置自身的rds.命名空间下而静态路由配置的 VHDS 订阅则不带rds.前缀——排查指标时需注意这一层级差异。八、源码与测试佐证8.1 核心实现路径source/common/router/vhds.ccVhdsSubscription的创建与回调实现。包括createVhdsSubscription对DELTA_GRPC/ADS(Delta) 的强校验、onConfigUpdate中对 added resources 与 aliases 的处理空资源直接跳过、updateOnDemand触发按需订阅以及失败时保证服务启动继续的容错逻辑init_target_.ready()。source/common/router/vhds.hVhdsSubscription类声明与VhdsStats统计结构。source/common/router/route_config_update_receiver_impl.cconRdsUpdate/onVhdsUpdate分别维护 RDS 与 VHDS 两份 VirtualHost 映射最终通过rebuildRouteConfigVirtualHosts合并成完整路由配置——这正是RDS 来的走 RDS 更新、VHDS 来的走 VHDS 更新的底层实现。source/common/router/config_impl.cc路由配置解析时通过config.has_vhds()记录uses_vhds_标志驱动后续按需行为。8.2 测试用例仓库内的 test/common/router/vhds_test.cc 覆盖了 VHDS 的关键行为可作为理解协议语义的补充参考配置源校验DELTA_GRPC下实例化成功非 Delta 配置、ADS 但 bootstrap 未配置 ADS、ADS 但api_type不是DELTA_GRPC等场景均失败更新行为VhdsAddsVirtualHostsVHDS 新增 VirtualHost、RdsUpdatesVirtualHostsRDS 通道更新、VhdsUpdateWithoutChangesKeepsTheRouteConfig无变更的空更新不重建路由配置对应empty_update统计的语义、VhdsUpdateWithoutChangesClearsTheResourceIdsOfTheLastUpdate等。结语VHDS 通过将 Delta xDS 的增量订阅能力引入 VirtualHost 分发把路由配置全量广播变成VirtualHost 按需拉取是 Envoy 在大规模服务网格中缓解配置下发压力的关键机制。理解其资源命名规则从右往左解析、暂停—请求—恢复的路由解析流程、RDS/VHDS 双通道更新归属以及DELTA_GRPC/ADS(Delta) 的配置源约束是正确落地 VHDS 的前提。若结合 vhds.cc 等源码与 vhds_test.cc 测试用例进行二次开发或排障则可进一步掌握其内部状态机与统计语义。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表