Envoy xDS 协议深度指南:REST 与 gRPC 动态发现机制的完整解析

发布时间:2026/9/12 22:36:10

Envoy xDS 协议深度指南:REST 与 gRPC 动态发现机制的完整解析 Envoy xDS 协议深度指南REST 与 gRPC 动态发现机制的完整解析【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy导读xDS 是 Envoy 实现控制面management server与数据面Envoy 实例动态配置交互的统称覆盖监听器、路由、集群、端点、密钥与运行时配置等全部核心资源的发现协议。本文以 Envoy 官方 xDS 协议文档为主体系统讲解 xDS 的资源类型与版本化体系、文件系统/流式 gRPC/REST-JSON 三种订阅方式、SotW 与 Incremental 四种传输变体、ACK/NACK 语义、TTL、ADS 与增量 xDS 的完整工作流程并结合仓库内 discovery.proto、ads.proto 等源码与 ads.yaml 配置示例帮助读者理解 xDS 协议细节并具备编写控制面与排查数据面问题的基础能力。Envoy 通过文件系统或查询一个或多个管理服务器来发现各种动态资源。这些发现服务及其对应 API 统称为xDS。资源通过**订阅subscription**机制获取指定一个待监视的文件系统路径、发起 gRPC 流、或轮询 REST-JSON URL。后两种方式需要携带DiscoveryRequestproto 负载所有方式的资源都通过DiscoveryResponseproto 负载交付。xDS 资源类型与 type URL每种 xDS 配置资源都关联一个类型resource type。资源类型遵循 版本化方案其版本独立于下文介绍的传输层版本。当前 v3 xDS 支持以下资源类型资源类型proto message说明envoy.config.listener.v3.Listener监听器LDSenvoy.config.route.v3.RouteConfiguration路由配置RDSenvoy.config.route.v3.ScopedRouteConfiguration作用域路由配置SRDSenvoy.config.route.v3.VirtualHost虚拟主机VHDSenvoy.config.cluster.v3.Cluster集群CDSenvoy.config.endpoint.v3.ClusterLoadAssignment端点分配EDSenvoy.extensions.transport_sockets.tls.v3.SecretTLS 密钥SDSenvoy.service.runtime.v3.Runtime运行时配置RTDS协议中使用type URL标识资源类型形如type.googleapis.com/resource type例如集群资源的 type URL 为type.googleapis.com/envoy.config.cluster.v3.Cluster。在 Envoy 发出的各类请求以及管理服务器的响应中都会声明该 type URL。在 ADS 多路复用场景下type URL 是区分各逻辑子流的唯一依据见 discovery.proto 中DiscoveryRequest.type_url字段注释。从源码结构看各资源类型的 proto 定义分布于 api/envoy/config 下按领域划分的v3包中而作为传输层消息的DiscoveryRequest、DiscoveryResponse、DeltaDiscoveryRequest、DeltaDiscoveryResponse与Resource均定义在 api/envoy/service/discovery/v3/discovery.proto。API_VERSIONING.md 说明每个 proto 包以独立的主版本命名如envoy.service.discovery.v3同一主版本内不允许破坏性变更保证线上数据面与控制面跨版本兼容。Protoc-Gen-ValidatePGV注解各 xDS 资源类型的 protobuf 消息带有protoc-gen-validatePGV注解用于表达语义约束供客户端在收到资源时校验其内容。需要注意以下几点客户端并非必须使用 PGV 注解做校验例如 Envoy 会做该校验而 gRPC 客户端不做PGV 注解也并非客户端应执行的全部校验清单客户端可能因与 PGV 注解无关的原因拒绝资源。通常情况下PGV 注解不应被控制面或 xDS 代理直接使用。控制面有时可以用它提前发现配置问题在资源进入控制面时就拒绝非法输入而不用等到发送给客户端之后但这只是个别场景的补充手段。随着 xDS API 演进PGV 注解会不断变化且放宽 PGV 注解不视为API 的破坏性变更。因此控制面不能假设其所有客户端编译时使用的 xDS proto 版本与自己一致也就无法断定客户端会执行与服务器相同的校验——这可能导致服务器拒绝一个客户端本可接受的资源。三种订阅方式的总体框架xDS 的所有订阅方式都建立在统一的请求/响应消息模型之上客户端发送DiscoveryRequest声明订阅的资源名、type URL、节点标识、版本与 nonce管理服务器返回DiscoveryResponse携带资源列表、版本与 nonce。两者的字段语义在 discovery.proto 中有精确定义DiscoveryRequest.version_info客户端最近一次成功处理响应的版本首次请求为空每次收到响应后客户端只有在准备好 ACK/NACK 时才会发送新请求。DiscoveryRequest.resource_names要订阅的资源名列表为空表示订阅该 API 的全部资源LDS/CDS 可空此时响应会隐含一批需要通过 EDS/RDS 显式枚举获取的资源。DiscoveryRequest.response_nonce对应被 ACK/NACK 的DiscoveryResponse的 nonce仅在非持久流或客户端尚未接受任何更新时可为空。DiscoveryRequest.error_detail前一次响应更新配置失败时填充google.rpc.Statusmessage 字段提供 Envoy 内部异常信息仅用于人工调试其字符串不保证跨版本稳定。DiscoveryResponse.version_info响应数据的版本。DiscoveryResponse.resources响应资源为google.protobuf.Any列表具体类型由所调用的 API 决定。DiscoveryResponse.noncegRPC 订阅中用于在下一次DiscoveryRequest中显式 ACK 特定DiscoveryResponse的标识。DiscoveryResponse.canary用于支持--terminate-on-canary-transition-failure与--dry-run-canary两个命令行标志的灰度发布能力。文件系统订阅文件系统订阅是最简单的动态配置交付方式将配置放在ConfigSource指定的已知路径下Envoy 使用inotifymacOS 上为kqueue监视文件变化并在更新时解析文件中的DiscoveryResponseproto。DiscoveryResponse支持二进制 protobuf、JSON、YAML 与 proto text 四种格式。文件系统订阅没有任何 ACK/NACK 机制仅有 stats 计数与日志可观测。如果一次配置更新被拒绝该 xDS API 的上一个有效配置会继续生效——这也是所有订阅方式共有的失败保留旧配置的默认行为。流式 gRPC 订阅API 流程配置树的根与依赖对于典型的 HTTP 路由场景客户端核心资源类型为Listener、RouteConfiguration、Cluster与ClusterLoadAssignment。依赖关系为每个Listener可指向一个RouteConfiguration后者可指向一个或多个Cluster每个Cluster可指向一个ClusterLoadAssignment。Envoy 在启动时先拉取全部Listener与Cluster资源然后拉取这些资源所需的RouteConfiguration与ClusterLoadAssignment。本质上每个Listener或Cluster资源都是 Envoy 配置树某一部分的根。非代理客户端如 gRPC则可能只拉取自己关心的特定Listener资源再按依赖链依次拉取对应 RDS/CDS/EDS 资源——此时最初的Listener资源就是该客户端配置树的根。xDS 传输协议的四种变体流式 gRPC 场景下xDS 传输协议有四种变体覆盖两个正交维度维度一State of the WorldSotW全量状态 vs 增量Incremental。SotW 是 xDS 最初的机制客户端每次请求都必须列出其关心的全部资源名对于 LDS/CDS服务器每次响应必须返回客户端已订阅的全部资源。例如客户端已订阅 99 个资源想再增加 1 个就必须发送包含全部 100 个资源名的请求服务器也要返回全部 100 个资源哪怕其中 99 个没有变化。这是明显的可扩展性瓶颈于是引入了增量协议客户端与服务器只表达相对上一次状态的差值——客户端可单独增/删某个资源名的订阅而不重发未变化的资源服务器只发送发生变化资源的更新增量协议还支持资源的懒加载lazy loading。维度二每种资源类型独立 gRPC 流 vs 所有资源类型聚合到单条 gRPC 流。前者是 xDS 最初的机制提供最终一致性模型后者为需要显式控制更新顺序的环境而引入。于是得到四种变体State of the WorldBasic xDSSotW 每种资源类型独立流Incremental xDS增量 每种资源类型独立流Aggregated Discovery ServiceADSSotW 聚合流Incremental ADS增量 聚合流各变体对应的 RPC 服务与方法非聚合变体下每种资源类型有独立的 RPC 服务每个服务同时提供 SotW 与增量两种方法资源类型服务Discovery ServiceSotW 方法Incremental 方法ListenerListener Discovery Service (LDS)StreamListenersDeltaListenersRouteConfigurationRoute Discovery Service (RDS)StreamRoutesDeltaRoutesScopedRouteConfigurationScoped Route Discovery Service (SRDS)StreamScopedRoutesDeltaScopedRoutesVirtualHostVirtual Host Discovery Service (VHDS)N/ADeltaVirtualHostsClusterCluster Discovery Service (CDS)StreamClustersDeltaClustersClusterLoadAssignmentEndpoint Discovery Service (EDS)StreamEndpointsDeltaEndpointsSecretSecret Discovery Service (SDS)StreamSecretsDeltaSecretsRuntimeRuntime Discovery Service (RTDS)StreamRuntimeDeltaRuntime聚合变体把所有资源类型多路复用multiplex到单条 gRPC 流上每种资源类型作为聚合流内独立的逻辑子流SotWAggregatedDiscoveryService.StreamAggregatedResourcesIncrementalAggregatedDiscoveryService.DeltaAggregatedResources这两个 RPC 的定义见 api/envoy/service/discovery/v3/ads.proto均为 gRPC-only 的双向流接口StreamAggregatedResources(stream DiscoveryRequest) returns (stream DiscoveryResponse)与DeltaAggregatedResources(stream DeltaDiscoveryRequest) returns (stream DeltaDiscoveryResponse)。所有 SotW 方法的请求/响应类型为DiscoveryRequest/DiscoveryResponse所有增量方法的请求/响应类型为DeltaDiscoveryRequest/DeltaDiscoveryResponse。配置使用哪种变体xDS API 中ConfigSource消息指明如何获取某类资源若ConfigSource内含 gRPCApiConfigSource则指向管理服务器的上游集群Envoy 会为每种 xDS 资源类型发起独立的双向 gRPC 流可分别指向不同的管理服务器。若ConfigSource内含AggregatedConfigSource则告诉客户端使用ADS。当前客户端需要一些本地配置来指明如何获取Listener与Cluster资源Listener资源可携带ConfigSource指明RouteConfiguration的获取方式Cluster资源可携带ConfigSource指明ClusterLoadAssignment的获取方式。客户端配置。在 Envoy 中bootstrap 文件包含两个ConfigSource一个指明Listener资源如何获取另一个指明Cluster资源如何获取此外还有一个独立的ApiConfigSource指明如何联系 ADS 服务器——只要任何ConfigSourcebootstrap 中的、或从管理服务器获取的Listener/Cluster资源中的内含AggregatedConfigSource就会使用这个 ADS 配置。使用 xDS 的 gRPC 客户端如 gRPC xDS 解析器只支持 ADSbootstrap 中只需给出 ADS 服务器名称其Listener/Cluster资源中的ConfigSource必须使用AggregatedConfigSource。一个已知限制任何 xDSCluster资源应放在 Bootstrap 配置static_resources字段中、任何依赖该 xDS 集群的静态Cluster之前否则会导致 Envoy 初始化变慢。典型例子是某个集群依赖 xDSCluster通过 SDS 为传输套接字配置密钥则这个 xDSCluster必须排在带有传输套接字密钥的集群之前。传输协议基础传输 API 版本。除资源类型版本外xDS 线上协议还有自己的传输版本用于对DiscoveryRequest/DiscoveryResponse等消息做类型版本化并编码进 gRPC 方法名中——服务器可以根据客户端调用的是哪个方法判断其使用的版本。基本协议流程。每条 xDS 流以客户端的DiscoveryRequest开始其中包含要订阅的资源列表、订阅资源对应的 type URL、节点标识以及可选的资源类型实例版本表示客户端已见过的最新版本详见 ACK/NACK 一节。随后服务器发送DiscoveryResponse内含自客户端上次声明的资源类型实例版本以来发生变化、且客户端已订阅的资源此后服务器可在订阅资源变化时随时追加发送响应。客户端每收到一个新响应都会再发送一个请求指明响应中各个资源单独来看是否有效ACK/NACK。nonce 与节点标识。所有服务器响应都带nonce字段客户端后续所有请求必须把response_nonce设为该流上最近收到的 nonce。这让服务器能确定某请求对应哪个响应避免 SotW 变体中的各类竞态。注意 nonce 只在单条 xDS 流上下文内有效流重启后失效在聚合变体中nonce 按资源类型分别跟踪。一条流上只有第一个请求保证携带节点标识后续请求可携带空节点标识无论响应是否被接受若节点标识多次出现其值必须始终一致因此服务器只需检查首条消息即可。ACK/NACK 与资源类型实例版本每种 xDS 资源类型都有一个版本字符串该类型下任一资源发生变化版本随之更新。服务器响应的version_info表示该资源类型的当前版本客户端随后发回请求其version_info表示客户端看到的最新有效版本——服务器据此判断何时发出了客户端认为无效的版本。在增量变体中资源类型实例版本由服务器通过DeltaDiscoveryResponse.system_version_info字段发送但客户端并不用它来通信哪些资源有效增量 API 有独立机制。版本是按资源类型分别维护的使用聚合变体时即便所有类型都在同一流上每种类型仍各有版本版本也按 xDS 服务器由唯一ConfigSource标识分别维护从多个服务器获取同类型资源时各服务器对版本有各自的认知。版本是资源本身的属性而非流的属性若流断开后客户端重建新流新流上的首个请求应携带上一条流上客户端见到的最新版本。服务器可在确定客户端没有订阅新资源时优化为不重发客户端已见过的资源例如 LDS/CDS 只有通配订阅时或客户端总是订阅完全相同的资源集合的环境。一个 EDS 请求示例YAML 形式version_info: node: { id: envoy } resource_names: - foo - bar type_url: type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment response_nonce:管理服务器可以立即回复也可以等到请求的资源就绪时再回复例如version_info: X resources: - foo ClusterLoadAssignment proto encoding - bar ClusterLoadAssignment proto encoding type_url: type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment nonce: A处理完DiscoveryResponse后Envoy 会在流上发送新请求指明最后成功应用的版本与管理服务器提供的 nonce。版本为 Envoy 与管理服务器提供了当前已应用配置的共享认知也是 ACK/NACK 配置更新的机制。ACK。如果更新中所有资源都有效version_info将设置为XACK 仅表示客户端认为响应中每个资源在单独评估时是有效的。NACK。如果 Envoy 发现配置更新X中的某些资源无效它会回复携带error_detail且version_info为先前版本本例为初始空版本的请求。注意 NACK不意味着所有资源都被拒绝error_detail的 message 字段包含精确的错误信息时序图中消息缩写格式约定DiscoveryRequest(Vversion_info, Rresource_names, Nresponse_nonce, Ttype_url)DiscoveryResponse(Vversion_info, Rresources, Nnonce, Ttype_url)NACK 之后一次 API 更新可能在新版本Y上成功服务器检测 NACK 的首选机制是检查客户端请求中是否存在error_detail字段。部分较老的服务器则通过同时观察版本与 nonce 判断若请求中的版本与服务器随该 nonce 发出的版本不一致则客户端拒绝了最新版本。但该方法对 LDS/CDS 之外的 API 不成立——当客户端动态改变订阅资源集合时除非服务器设法在任意客户端订阅新资源时递增资源类型实例版本仅靠版本nonce 无法可靠识别 NACKACK 与 NACK 语义总结xDS 客户端应对收到的每个DiscoveryResponse执行 ACK 或 NACKresponse_nonce告诉服务器该 ACK/NACK 对应其哪个响应。ACK表示各资源单独有效、客户端意图应用它们但不表示配置已成功应用——客户端发出 ACK 后仍可能应用失败。ACK 携带DiscoveryResponse中的version_info。NACK表示响应中至少一个资源无效以error_detail字段存在为标志。version_info表示客户端正在使用的最新版本在客户端已订阅新资源且该新资源无效的场景下该版本可能并非更旧的版本。何时发送更新管理服务器只应在资源变化时向 Envoy 客户端发送更新。Envoy 会在接受或拒绝每个DiscoveryResponse后立即用携带 ACK/NACK 的DiscoveryRequest回复。若服务器未等变化发生就反复提供相同资源集合会在客户端与服务器两侧造成无谓工作可能带来严重性能影响。流内新的DiscoveryRequest会取代同一资源类型先前的DiscoveryRequest因此管理服务器对每条流上的任意资源类型只需响应最新的请求。客户端如何指定要返回的资源xDS 请求允许客户端以资源名集合的形式向服务器提示自己关心的资源。SotW 变体通过DiscoveryRequest.resource_names指定增量变体通过DeltaDiscoveryRequest.resource_names_subscribe与resource_names_unsubscribe指定。一般情况下下述通配订阅除外请求必须指定客户端关心的资源名集合服务器必须提供存在的被请求资源客户端会静默忽略未被显式请求却被提供的资源。当客户端发送新请求改变资源集合时服务器必须重发任何新请求的资源即使此前未经请求已发过且资源未变化。资源名列表变为空表示客户端不再关心该类型的任何资源。通配订阅。对于Listener与Cluster资源类型还存在通配订阅订阅特殊名称*即触发。此时服务器应使用站点特有的业务逻辑通常基于客户端的node标识确定客户端关心的完整资源集合。历史遗留语义出于历史原因若客户端对某资源类型发起请求但从未显式订阅过任何资源名SotW该流上该类型的所有请求resource_names均为空增量该流上从未对该类型发送过带非空resource_names_subscribe的请求服务器应将其与显式订阅*等同对待。但一旦客户端显式订阅了某个资源名无论是*还是其他名字该遗留语义即失效此后清空订阅列表将被解释为取消订阅见下文而非订阅*。SotW 举例客户端发送resource_names未设置的请求 → 服务器解释为订阅*。客户端发送resource_names为*与A→ 服务器解释为继续订阅*并新增订阅A。客户端发送resource_names为A→ 服务器解释为取消订阅*、继续订阅A。客户端发送resource_names未设置 → 服务器解释为取消订阅A客户端已取消全部订阅。虽然该请求与第一条完全相同但因该流上此类型此前已有设置过resource_names的请求故不再解释为通配订阅。增量举例客户端发送resource_names_subscribe未设置 → 服务器解释为订阅*。客户端发送resource_names_subscribe为A→ 服务器解释为继续订阅*并新增订阅A。客户端发送resource_names_unsubscribe为*→ 服务器解释为取消订阅*、继续订阅A。客户端发送resource_names_unsubscribe为A→ 服务器解释为取消订阅A已取消全部订阅。虽然订阅集合再次为空但同样不再解释为通配订阅。客户端行为。Envoy 对Listener与Cluster资源总是使用通配订阅而其他 xDS 客户端如使用 xDS 的 gRPC 客户端可显式订阅特定资源名例如它们只有一个单例监听器且已通过带外配置知道其名字。资源在响应中的分组方式增量变体中服务器每个资源单独放在一个响应里若已发送 100 个资源而只有 1 个变化只需发送包含该变化资源的响应无需重发另外 99 个客户端也不得删除未变化的资源。SotW 变体中除Listener与Cluster外的资源类型与增量一样按资源分组但Listener与Cluster采用完整世界状态服务器必须包含客户端所需的该类型全部资源即使它们自上次响应以来没有变化。也就是说已发送 100 个资源而只有 1 个变化时必须全部 100 个重发。还需注意所有变体都以完整命名的资源为操作单位不存在对命名资源内重复字段做增量更新的机制——最典型的是目前没有在 EDS 响应中增量更新单个端点的机制。重复资源名单个响应中出现同一资源名两次是服务器错误客户端应 NACK 含同一资源名多个实例的响应。删除资源增量变体中服务器通过响应的removed_resources字段告知客户端应删除的资源客户端将其从本地缓存移除。SotW 变体删除规则更复杂对Listener与Cluster若新响应中不再出现先前见过的资源即表示该资源已删除客户端必须删除空响应表示删除该类型全部资源。对其他资源类型API没有提供服务器告知客户端资源被删除的机制删除通过父资源变更隐式体现例如收到 LDS 更新移除了此前指向RouteConfigurationA 的Listener且没有其他Listener再指向 A则客户端可删除 A。对这些类型空DiscoveryResponse对客户端而言实际是 no-op。资源不存在时如何获知SotW 变体没有任何显式机制判断所请求的资源不存在。Listener/Cluster响应必须包含客户端请求的全部资源但客户端不能仅凭响应缺失就断定资源不存在——因为更新是最终一致的若客户端先请求A又请求A与B随后看到一个只含A的响应它不能断定B不存在因为该响应可能是基于第一个请求、在服务器看到第二个请求之前发出的。对其他资源类型因每个资源可独立成响应下一次响应可能是另一个已订阅资源的无关更新同样无法据此判断新请求的资源是否存在。因此客户端应在发送新资源请求后使用超时建议 15 秒判断资源不存在超时未收到即视为不存在。Envoy 在 资源预热 期间对RouteConfiguration与ClusterLoadAssignment使用该机制。此外即使客户端请求时资源不存在该资源随时可能被创建管理服务器必须记住客户端请求的资源集合一旦其中某资源随后出现必须向客户端推送包含该新资源的更新。因此初始看到资源不存在的客户端必须随时准备资源被创建。取消订阅资源增量变体中通过resource_names_unsubscribe字段取消订阅。SotW 变体中每个请求必须包含resource_names的完整列表取消订阅即发送一个仅含仍在订阅资源名的新请求例如先前订阅A与B想取消B必须发送只含A的新请求。注意对使用通配订阅的Listener/Cluster资源集合由服务器而非客户端决定客户端无法单独取消订阅其中某个资源只能整体取消通配订阅。单条流上请求多个资源对 EDS/RDSEnvoy 可能为同类型的每个资源各建一条独立流例如每个ConfigSource各有独立的管理服务器上游集群也可能把发往同一管理服务器的多个资源请求合并到一条流。具体实现细节可自由选择但管理服务器应能处理每个请求中同一资源类型的一个或多个resource_names。以下两种时序均合法地获取两个 EDS 资源{foo, bar}同一条流上的多个 EDS 请求eds-same-stream.svg不同流上的多个 EDS 请求eds-distinct-stream.svg资源更新与竞态如前述Envoy 在 ACK/NACK 特定DiscoveryResponse的每个DiscoveryRequest中都会更新resource_names列表。此外Envoy 还可能在同一version_info下发出额外的DiscoveryRequest来更新资源提示例如 Envoy 处于 EDS 版本X且只知道集群foo随后收到 CDS 更新得知bar它会以X版本、resource_names为{foo,bar}再发一个DiscoveryRequest这里存在一个竞态Envoy 在X发出资源提示更新后、服务器处理该更新前服务器用新版本Y回复则资源提示更新可能被误读为以X版本拒绝Y。为避免此问题服务器用nonce让 Envoy 标明每个DiscoveryRequest对应的具体DiscoveryResponse管理服务器不应对携带陈旧 nonce 的DiscoveryRequest发送DiscoveryResponse。当更新的 nonce 呈现给 Envoy 后旧 nonce 即变陈旧服务器无需在确定有新版本前发送更新此前的同版本请求也随之陈旧。服务器可在新版本就绪前处理多个同版本的DiscoveryRequest上述资源更新时序的一个推论是Envoy不期望自己发出的每个DiscoveryRequest都得到DiscoveryResponse。资源预热Cluster 与 Listener 在被更新后以及 Envoy 初始化期间都要经过**预热warming**才能开始服务请求Cluster的预热只有在管理服务器提供ClusterLoadAssignment响应后才算完成。若Listener引用了 RDS 配置其预热只有在管理服务器提供RouteConfiguration后才算完成。管理服务器应在预热期间提供 EDS/RDS 更新。若管理服务器不提供 EDS/RDS 响应Envoy 在初始化阶段将无法完成初始化经 CDS/LDS 发送的更新也要等到 EDS/RDS 响应提供后才会生效。Envoy 具体实现说明Cluster预热只有在管理服务器提供新的ClusterLoadAssignment响应后才完成即使端点没有变化也是如此预热超时后若集群存在缓存的ClusterLoadAssignmentEnvoy 会使用该缓存。Listener预热即使管理服务器未对Listener引用的RouteConfiguration发送响应也会完成Envoy 会用此前发送过的RouteConfiguration完成预热管理服务器仅在RouteConfiguration已变化或从未发送过时才需发送响应。最终一致性考量由于 Envoy 的 xDS API 是最终一致的更新期间可能出现短暂的流量中断。例如CDS/EDS 只知道集群X一个RouteConfiguration引用X恰在提供Y的 CDS/EDS 更新之前被调整为引用Y则流量会被黑洞直到 Envoy 实例获知Y。对某些应用短时流量中断可以接受客户端重试或其他 Envoy sidecar 可掩盖该中断。对无法容忍中断的场景可以通过先提供同时包含X与Y的 CDS/EDS 更新、再做将X重指向Y的 RDS 更新、最后提供移除X的 CDS/EDS 更新来避免。一般而言为避免流量中断更新应按make-before-break模型排序CDS 更新如有必须总是最先推送。EDS 更新如有必须在对应集群的 CDS 更新之后到达。LDS 更新必须在对应 CDS/EDS 更新之后到达。与新加监听器相关的 RDS 更新必须在 CDS/EDS/LDS 更新之后到达。与新加 RouteConfiguration 相关的 VHDS 更新如有必须在 RDS 更新之后到达。之后才能移除陈旧的 CDS 集群及不再被引用的相关 EDS 端点。如果没有新增集群/路由/监听器或可接受更新期间短暂断流xDS 更新可独立推送。注意LDS 更新时监听器会先预热再接收流量即通过 RDS 获取依赖路由集群在增删改时会预热而路由不会预热——管理面必须在推送路由更新前确保路由引用的集群已就位。TTL资源过期机制当管理服务器不可达时Envoy 保留最后已知配置直到连接重建。但某些场景不希望如此例如故障注入服务管理服务器恰在错误时机崩溃可能让 Envoy 停留在不期望的状态。TTL 设置允许 Envoy 在与管理服务器失联超过指定时长后移除一组资源例如可用来在管理服务器不可达时终止故障注入测试。支持xds.config.supports-resource-ttl客户端特性的客户端可在每个 Resource 上指定 TTL 字段。每个资源有独立的 TTL 过期时间到期即过期每种 xDS 类型可有不同的过期处理方式。更新 TTL管理服务器重发带新 TTL 的资源。移除 TTL管理服务器重发 TTL 字段未设置的资源。轻量心跳heartbeat可发送一个resource字段未设置、version与最近发送版本一致的Resource来仅更新 TTL这类资源不会被视为资源更新只作为 TTL 更新。从 discovery.proto 中Resource消息的字段注释可见每个资源收到新 TTL 时计时器重置收到无 TTL 的资源时计时器移除计时器到期后该资源配置被移除。SotW TTLSotW 使用 TTL 时相关资源必须包裹在Resource中——这样可让 Delta xDS 使用的 TTL 字段复用于 SotW 而无需改动 SotW API。SotW 同样支持心跳响应中任何形似心跳的资源只用于更新 TTL。该特性由xds.config.supports-resource-in-sotw客户端特性门控。聚合发现服务ADS在管理服务器分布式部署时提供上述排序保证以避免流量中断颇具挑战。ADS 允许单个管理服务器通过单条 gRPC 流交付所有 API 更新从而可以仔细编排更新顺序以避免断流。ADS 用一条流承载多条独立的DiscoveryRequest/DiscoveryResponse序列通过 type URL 多路复用对任意给定 type URL上述请求/响应排序规则依然适用。示例更新序列每个 Envoy 实例可建立一条ADS 流。ADS 的完整 bootstrap 配置示例见 docs/root/_include/ads.yamlnode: # set cluster identifier cluster: envoy_cluster # set node identifier id: envoy_node dynamic_resources: ads_config: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: ads_cluster cds_config: ads: {} lds_config: ads: {} static_resources: clusters: - name: ads_cluster type: STRICT_DNS load_assignment: cluster_name: ads_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: # set ADS management server address address: my-control-plane # set ADS management server port port_value: 777 # It is recommended to configure either HTTP/2 or TCP keepalives in order to detect # connection issues, and allow Envoy to reconnect. TCP keepalive is less expensive, but # may be inadequate if there is a TCP proxy between Envoy and the management server. # HTTP/2 keepalive is slightly more expensive, but may detect issues through more types # of intermediate proxies. typed_extension_protocol_options: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: type: type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicit_http_config: http2_protocol_options: connection_keepalive: interval: 30s timeout: 5s upstream_connection_options: tcp_keepalive: {}要点dynamic_resources.ads_config定义 ADS 服务器api_type: GRPC指向名为ads_cluster的上游集群cds_config与lds_config都使用ads: {}声明从 ADS 获取ads_cluster作为静态集群定义在static_resources中通过 STRICT_DNS 解析到控制面地址。配置文件同时给出 HTTP/2 keepalive30s 间隔 / 5s 超时与 TCP keepalive 两种连接保活建议用于尽早发现连接问题并触发重连。增量 xDSIncremental xDS增量 xDS 是一个独立的 xDS 端点其价值在于线上协议以资源/资源名的差值Delta xDS通信支持 xDS 资源的可扩展性修改 10 万个集群中的 1 个时管理服务器只需交付这 1 个变化的集群而非全部。允许 Envoy按需/懒加载额外资源例如只有在该集群的请求到达时才请求该集群。增量 xDS 会话总是处于 gRPC双向流上下文中服务器可跟踪所连接 xDS 客户端的订阅状态。目前尚无REST 版增量 xDS。增量线上协议中nonce 字段必需用于将DeltaDiscoveryResponse与DeltaDiscoveryRequest的 ACK/NACK 配对响应的消息级system_version_info可选仅用于调试。DeltaDiscoveryRequest可在以下时机发送xDS 双向 gRPC 流的初始消息。对先前DeltaDiscoveryResponse的 ACK 或 NACK此时response_nonce设为响应中的 nonce 值ACK/NACK 由error_detail的缺失/存在决定。客户端自发的DeltaDiscoveryRequest用于动态增删被跟踪的resource_names集合此时response_nonce必须省略。注意即使请求携带response_nonce服务器必须遵从订阅状态的变化哪怕 nonce 已陈旧。nonce 只用于关联 ACK/NACK 与服务器响应不应用来拒绝陈旧请求。首个示例中客户端连接并收到首个更新后 ACK第二个更新失败后 NACK随后 xDS 客户端自发请求wc资源重连时增量 xDS 客户端可通过initial_resource_versions告诉服务器自己已知的资源及其版本避免网络重传。由于不假定新流保留上一流的状态重连客户端必须提供其关心的全部资源名对通配订阅请求必须在resource_names_subscribe中指定*或遗留行为使resource_names_subscribe与resource_names_unsubscribe均为空。资源名与别名。资源通过资源名或别名标识。资源的别名如有通过DeltaDiscoveryResponse中Resource的aliases字段体现资源名通过name字段返回。DeltaDiscoveryRequest的订阅/取消订阅字段均接受资源名或别名判断是否已订阅时应同时检查名字与别名discovery.proto 中Resource消息定义。订阅资源。客户端在resource_names_subscribe中发送别名或名字即可订阅。即使服务器认为客户端已订阅某资源且持有其最新版本也必须在响应中提供这些资源——因为存在对服务器不可见的实现细节客户端可能看起来仍处于订阅状态却已遗忘这些资源。取消订阅。客户端失去兴趣时在resource_names_unsubscribe中指示同样接受资源名或别名。该字段可能包含服务器认为客户端本就未订阅的多余资源名服务器应干净地处理直接忽略这些幽灵取消订阅。多数情况下仅取消订阅而不做其他事的请求无需任何响应但有一个例外当客户端同时有通配订阅*与对另一具体资源名的订阅时该具体资源名可能也被通配覆盖客户端取消它后无法确定是否继续缓存该资源——此时服务器必须发送响应把该具体资源放入removed_resources若不被通配覆盖或resources若被通配覆盖。资源不存在。增量变体中订阅的资源不存在时服务器会发送DeltaDiscoveryResponse把该资源名放入removed_resources字段。客户端据此无需等待超时即可快速判断资源不存在SotW 则需要超时机制但客户端仍应使用超时兜底防止管理服务器未及时响应。REST-JSON 轮询订阅xDS 单例 APIsingleton APIs还支持通过 REST 端点进行同步长轮询。消息排序与上述类似但与管理服务器之间不维持持久流。任意时刻只应有一个未完成的请求因此 REST-JSON 中response_nonce可选。DiscoveryRequest与DiscoveryResponse使用 proto3 的JSON 规范变换JSON canonical transform编码。ADS 不适用于 REST-JSON 轮询。当轮询周期设置得很小意图做长轮询时还有一个要求除非底层资源发生了 资源更新否则不得发送DiscoveryResponse——否则长轮询将退化为无谓的空转。结语xDS 协议是 Envoy 控制面与数据面解耦的基石资源类型与 type URL 构成寻址基础文件系统/gRPC 流/REST-JSON 三种订阅方式覆盖从单机到大规模控制面的部署形态SotW 与增量、单流与聚合流的二维组合提供从简单到高扩展性的传输选择ACK/NACK 与 nonce 保证配置交付的可靠性与顺序性TTL 提供失联场景下的配置回收能力。掌握本文所述的协议细节——尤其是 ADS 的 make-before-break 更新排序与增量 xDS 的订阅状态机——是开发管理服务器或深度定制 Envoy 数据面的前提。进一步的源码细节可继续查阅 discovery.proto、ads.proto 以及 ads.yaml 示例配置。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/12 22:31:09

从Brave迁移到Tavily:API稳定性与性能优化指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/12 22:31:09

YOLOv8 3D识别与机械臂抓取实战:从环境配置到GUI界面

简介:面向机器人先进视觉赛的深度学习实战项目,这份压缩包提供基于YOLOv8的3D目标识别与分割完整源码,并自带GUI界面,支持深度图像处理与分析。资源特别适合高校学生作为毕业设计、课程设计或日常作业参考,也适合科研与…

2026/9/12 23:36:15

Redis String编码原理与44字节边界压测实战

1. 测试环境与 12 轮压测方案设计先交代一下这次实测的来龙去脉。我是在一次面试候选人时聊到 Redis String 编码,对方把“44 字节”背得很熟,但问到他“为什么是 44,不是 32,也不是 64”就答不上来了。这个情况其实很普遍&#x…

2026/9/12 23:36:15

HCM150P10L在电动车控制器中的热与可靠性设计解析

1. 这颗PMOS管到底解决了电动车里什么真问题?最近在帮几家做中高端电动自行车控制器的客户做器件选型,反复被问到一个问题:“HCM150P10L这颗管子,到底值不值得替掉现在用的IRF4905或者STP16PF10?”——不是参数表上写着…

2026/9/12 23:36:15

基于Simulink的雷达射频前端建模仿真与链路预算验证方法

简介:Simulink环境下的雷达系统射频前端建模仿真资源,面向雷达系统设计、通信工程或信号处理方向的学习者与工程师,重点解决将RF前端行为融入整体雷达系统性能评估的问题。资源包含单站脉冲雷达与FMCW雷达两个Simulink模型,覆盖参…

2026/9/12 23:31:15

AI 手账排版工具公测上线:从内测反馈到正式发布的全流程

AI 手账排版工具公测上线:从内测反馈到正式发布的全流程九月第二周的周六,海风卷着微凉的秋意。在经历了一整周的内测反馈收集、微信 WebView 兼容性修复以及离屏 Canvas 性能优化后,「AI 智能手账排版工具(Tide Layout Maker&…

2026/9/12 2:05:33

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/12 3:55:12

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/12 10:09:03

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/12 0:04:17

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现

简介:本资源是一份面向智能优化算法研究者与MATLAB初学者的仿生智能算法实践代码包,聚焦于长鼻浣熊优化算法(COA)的多策略改进与性能验证。针对传统COA易陷局部最优、收敛精度不足等问题,作者融合Circle映射初始化提升…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/12 6:37:43

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码