【Envoy 数据面】ADS / SotW / Incremental:流、ACK/NACK 与 version/nonce
内容提要
本文介绍Envoy xDS协议四种传输变体(SotW/Delta与分类型流/ADS正交组合),解析version_info与nonce两套时钟机制,阐明ACK/NACK的协议承诺边界,并列出NACK后的失败模式。强调ACK不等于配置生效,NACK后旧配置继续服务,控制面需按CDS→EDS→LDS→RDS顺序推送以避免短暂黑洞。
延伸解读
选型:先定维度,再谈协议
xDS 的四种变体由两个正交维度组合而成:SotW/Delta 决定推送整表还是差量,分类型流/ADS 决定多流最终一致还是单流可排序。选型时应先明确核心诉求:要严格 make-before-break 顺序优先 ADS,要大规模 EDS 差量优先 Incremental,两者可叠加为 Incremental ADS。分类型 SotW 适合规模可控、容忍最终一致窗口的部署。
version_info 与 nonce:两套时钟,不可混用
version_info 是资源类型级别的版本时钟,按类型和管理端区分;nonce 是流内配对时钟,用于将响应与后续 ACK/NACK 配对。混用会导致误判 NACK,尤其在 RDS/EDS 等动态订阅场景。客户端可发出多个请求而不期望每个都有响应,服务端对陈旧 nonce 的请求不应回包。
ACK 不等于生效,NACK 不等于全拒
ACK 仅表示隔离校验通过并意图应用,不保证配置已生效或流量已切换;NACK 表示至少一个资源无效,但细节在 error_detail 中。检测 NACK 应首选 error_detail 是否存在,而非仅靠版本不一致推断。控制面若把 ACK 当作配置生效的 SLI,会漏掉 warming 失败或应用失败等真实故障。
NACK 后的失败模式与分类型流风险
NACK 后旧配置继续服务,不会自动回滚已生效的监听器;控制面需避免反复推送坏版本。分类型流存在最终一致窗口,RDS 已指向新集群而 CDS/EDS 未就绪时会出现短暂黑洞。协议建议按 CDS→EDS→LDS→RDS 顺序推送,ADS 降低多服务端抢序难度,但不免除控制面自身的排序责任。
Q&A
Envoy xDS协议有哪四种传输变体?它们是如何组合的?
Envoy xDS协议有四种传输变体,由两个正交维度组合而成:SotW(全量)与Incremental(增量)为一维,分类型流与ADS(聚合发现服务)为另一维。交叉得到:Basic xDS(SotW+分类型流)、Incremental xDS(Delta+分类型流)、ADS(SotW+单流多路复用)、Incremental ADS(Delta+单流多路复用)。
SotW和Incremental(Delta)推送方式有什么区别?各自适用什么场景?
SotW每次响应返回订阅集合的全集,缺席即删除,适合规模可控、可容忍最终一致窗口的部署;Incremental只发送增删改,适合大规模EDS场景,能减少带宽和抖动。
ADS(聚合发现服务)相比分类型流有什么优势?为什么推荐按CDS→EDS→LDS→RDS顺序推送?
ADS将所有类型复用一条gRPC流,支持按CDS→EDS→LDS→RDS顺序推送,降低短暂黑洞概率。分类型流存在最终一致窗口,控制面需按该顺序推送以避免短暂黑洞。ADS降低多服务端抢序难度,但不免除控制面按顺序推送的责任。
version_info和nonce在xDS协议中分别起什么作用?为什么不能混用?
version_info是资源类型级别的版本时钟,表示该类型资源的版本;nonce是流内配对时钟,用于将DiscoveryResponse与后续ACK/NACK配对。两者不能混用,因为nonce解决SotW特有竞态,若只看version_info,hint请求容易被误判为对Y的拒绝。
在Envoy xDS中,ACK和NACK分别表示什么?ACK是否等于配置已生效?
ACK表示各资源单独看有效,客户端意图应用,但不保证配置已成功落到可服务状态;NACK表示至少一个资源无效,旧配置继续服务。ACK不等于配置已生效或流量已切换,控制面不能把ACK当成金丝雀已吃到新路由。
当Envoy对某个xDS响应返回NACK后,数据面和控制面分别会怎样?
数据面会继续运行上一有效版本,不会自动回滚已生效的监听器;控制面若反复推送同一坏版本,会导致无意义CPU消耗,应修复资源或推送可ACK的新版本。