DNS 解析与缓存与动态服务发现

共 24 题
📑 题目列表 24 题
#
★★★

1. 递归解析器从根区到权威服务器如何迭代查询,胶水记录解决了什么循环依赖?

请说明递归解析器从根区到权威服务器进行迭代查询的过程,以及胶水记录(glue record)解决了什么循环依赖?

  • 递归与迭代查询流程
  • 根区到 TLD 到权威的逐级解析
  • 胶水记录与循环依赖

递归解析器收到查询后,先查根区(根服务器)获取 TLD 权威服务器的地址,再向 TLD 权威查询二级域名的权威服务器,再向该权威服务器查询具体的 A/AAAA 记录,逐级迭代直到拿到答案。为找到权威服务器,就需要知道其 IP 地址(NS 记录给出名称,还需要 A 记录给出 IP)。若某权威服务器的名称(及其 A 记录)位于它所管辖的域内,就形成"鸡生蛋"循环依赖(要知道该域的权威,需要该域内的 A 记录)。胶水记录(glue)在父区中同时提供 NS 的 A 记录(如 .com 的父区中直接给出 example.com 的 NS 的 IP),从而打破循环依赖,使解析器能直接联系权威地址。

迭代查询是"自顶向下逐级下探",胶水解决的是"父区要指向子区权威,权威地址又由子区提供"的循环。胶水是父区对子区权威地址的"预置映射"。

#
★★★

2. DNS-over-HTTPS(DoH)与 DNS-over-TLS(DoT)在握手开销、隐私与中间设备兼容上的取舍有哪些?

请对比 DNS-over-HTTPS(DoH)与 DNS-over-TLS(DoT)在握手开销、隐私保护和中间设备兼容性上的取舍?

  • DoH 与 DoT 的传输方式
  • 握手开销与延迟
  • 隐私与中间设备兼容

DoT 用专用端口 853 承载 TLS 加密的 DNS,DoH 用标准 HTTPS(端口 443,HTTP 之上封装 DNS)承载加密 DNS。握手开销上:DoH 因叠加 HTTP/2 或 HTTP/3 层,TLS 握手后还需 HTTP 层开销,通常比 DoT 略重;但 DoH 复用 443 端口,与普通 HTTPS 流量混在一起,不易被中间设备按端口识别/阻断,兼容性和抗干扰更好。隐私上两者都加密查询内容,防止窃听;但 DoH 把 DNS 混入 HTTPS 流量,更难被网络防火墙按端口识别,也能规避针对 853 的封锁,隐私性更强。取舍:DoT 解析性能略好、实现简单,但 853 端口易被识别/阻断;DoH 兼容性、抗封锁强,但性能略差且与 HTTP 层耦合。

核心取舍是"端口可见性":DoT 用固定 853 暴露 DNS 流量,DoH 混入 443 的 HTTPS 洪流。DoH 更抗封锁但开销略高,DoT 更精简但易被识别。

#
★★★

3. 负缓存如何依据 SOA MINIMUM 与响应 TTL 生效,NXDOMAIN 与 NODATA 应如何区分?

请说明负缓存(negative caching)如何依据 SOA 的 MINIMUM 字段与响应 TTL 生效,以及 NXDOMAIN 与 NODATA 应如何区分?

  • 负缓存与 SOA MINIMUM
  • NXDOMAIN(域名不存在)与 NODATA(存在但无此类型)
  • 负缓存 TTL 计算

负缓存对"不存在的记录"(NXDOMAIN 或 NODATA)进行缓存,避免重复查询。负缓存 TTL 由响应的 SOA 记录决定:取 SOA 的 MINIMUM 字段与 SOA 记录的 TTL 中较小者(RFC 2308),作为负缓存时长。NXDOMAIN 表示域名本身不存在(权威返回 NXDOMAIN,整个域名无效),负缓存可缓存整个域名的不存在;NODATA 表示域名存在但所请求的类型没有记录(如存在 A 但没有 AAAA,响应 NOERROR 但 ANSWER 为空),只缓存该类型不存在。区分方法:看响应码——NXDOMAIN 返回 RCODE=3,NODATA 返回 RCODE=0 且 ANSWER 为空(无该类型记录)。

负缓存降低了对不存在记录的重复查询负载,TTL 由 SOA MINIMUM 与 TTL 共同决定。NXDOMAIN 是"域名不存在",NODATA 是"域名存在但无此类型",二者语义不同、缓存粒度不同。

#
★★★

4. 权威 DNS 的 anycast 部署如何减少延迟与抗 DDoS,地域调度与健康探测如何协同?

请说明权威 DNS 的 anycast 部署如何减少延迟与抗 DDoS,以及地域调度与健康探测如何协同?

  • anycast 部署与就近性
  • 抗 DDoS(流量分散、隔离)
  • 地域调度与健康探测

权威 DNS 采用 anycast 部署,把同一组 IP 地址通告到多个地理位置,BGP 让用户路由到最近的节点,从而减少解析延迟;同时 anycast 天然分散流量,对单点 DDoS 攻击,攻击流量被分散到各处,且可隔离/清洗受影响节点,抗 DDoS 能力强。地域调度上,权威服务器可结合用户来源 IP 或 EDNS Client Subnet 返回就近/最优的解析结果,配合健康探测(检查各接入点、后端服务的可达性、容量、延迟),把不可达或过载的节点从 anycast 通告中摘除,或把用户流量调度到健康节点,实现容灾与负载均衡。协同机制:健康探测实时刷新 anycast 通告与调度策略,确保解析结果始终指向可用且优的节点。

anycast 解决"就近与抗 DDoS",健康探测解决"节点可用性",两者协同:探测决定哪些节点可通告/可调度,anycast 决定用户去哪。这是权威 DNS 高可用与高性能的关键。

#
★★★

5. DNS 查询的 QNAME minimization 与 QTYPE filtering 如何减少隐私泄露,与 ECS(edns-client-subnet)的取舍是什么?

请说明 DNS 查询的 QNAME minimization 与 QTYPE filtering 如何减少隐私泄露,并分析它们与 ECS(edns-client-subnet)的取舍?

  • QNAME minimization(最小化查询名)
  • QTYPE filtering(过滤查询类型)
  • ECS 与隐私的取舍

QNAME minimization(RFC 7816)让递归解析器在上游查询时只发送"必要的最少域名部分"(如先查 .com,再查 example.com,而不同时发送完整 FQDN),减少向权威服务器泄露完整查询名的风险。QTYPE filtering 是递归器按需请求特定类型(如只请求 A/AAAA)而非全量,减少信息暴露。两者都降低"上游权威看到完整查询"的隐私面。ECS(edns-client-subnet)则相反:它把客户端子网信息带到权威,使权威能返回更精确的地域结果(精细调度),但这也向权威泄露了客户端 IP 子网,与隐私目标冲突。取舍:QNAME minimization/QTYPE filtering 减少泄露、但可能牺牲部分精确性;ECS 提升精确性但增加泄露。需权衡隐私与调度精度。

QNAME 最小化与 QTYPE 过滤是"少给信息",ECS 是"多给信息换精度"。三者围绕"隐私 vs 精确调度"的平衡,现代递归器常在两者间按需配置。

#
★★★

6. DNSSEC 验证链中的 DS、DNSKEY、RRSIG、NSEC/NSEC3 分别承担什么职责?

请说明 DNSSEC 验证链中 DS、DNSKEY、RRSIG、NSEC/NSEC3 记录分别承担的职责?

  • DNSKEY 与 RRSIG 的签名/验证
  • DS 记录与链式信任
  • NSEC/NSEC3 的否定证明

DNSSEC 用一套记录建立信任链:DNSKEY 记录存放域的公开密钥(含 KSK 与 ZSK),用于验证该域数据的签名;RRSIG 记录是特定资源记录集的数字签名,由 ZSK 签名,验证者用 ZSK 的公开密钥验证 RRSIG 即可确认数据未被篡改。DS(Delegation Signer)记录位于父区,是对子区 DNSKEY 的哈希摘要,用来把信任从父区传递到子区(验证父区 DS 由父区 KSK 签名,再得到子区 DNSKEY),形成链式信任。NSEC/NSEC3 用于否定证明:NSEC 记录列出相邻域名,证明某域名/类型不存在(返回 NXDOMAIN/NODATA 的签名证明),NSEC3 用哈希的 NSEC 记录,避免泄露域名列表(zone walking)。

验证链是"父区 DS 验证子区 DNSKEY,子区 DNSKEY 验证子区 RRSIG"。DNSKEY 是公钥,RRSIG 是签名,DS 是链式关键,NSEC/NSEC3 是"证明不存在"的凭证。

#
★★★

7. NSEC3 相比 NSEC 在 zone walking 防御上做了什么,为何需要 salt 与额外 hash 迭代次数?

请说明 NSEC3 相比 NSEC 在防御 zone walking 上做了什么,以及为何需要 salt 与额外的 hash 迭代次数?

  • NSEC 会泄露域名列表(zone walking)
  • NSEC3 用哈希隐藏域名
  • salt 与迭代次数的作用

普通 NSEC 记录按域名顺序列出相邻记录,攻击者可以顺序遍历获得整个域名列表(zone walking),泄露所有域名。NSEC3 用密码学哈希对域名做哈希后再生成 NSEC 记录,域名的真实名称被隐藏,攻击者看不到明文域名,抵御 zone walking。为增强防御,NSEC3 引入 salt(盐)和迭代次数(iterations):salt 是每次签名时随机加入的盐值,使相同域名的哈希结果随 salt 变化,防止预计算字典攻击;迭代次数是对哈希函数重复计算的次数,增加暴力破解哈希的成本,使攻击者难以通过穷举反推域名。但 salt 与迭代次数增加也提高了验证开销,需权衡。

NSEC 以明文域名顺序泄露,NSEC3 用"哈希+盐+迭代"隐藏域名。salt 防预计算,迭代次数加破解成本,二者共同抵御 zone walking 与字典攻击。

#
★★★

8. 启用 DNSSEC 后某些 CDN 解析失败通常源于签名过期而非配置错误,自动化续签与监控要点是什么?

请说明启用 DNSSEC 后某些 CDN 解析失败往往源于签名过期而非配置错误,并给出自动化续签与监控要点?

  • DNSSEC 签名过期导致解析失败
  • 自动化续签(签名滚动、自动签名)
  • 监控要点

DNSSEC 的 RRSIG 有有效期(signature validity),若域名的 DNS 记录签名在权威设备上过期未续签,验证者验证时签名失效,解析会失败(SERVFAIL),表现为"某些 CDN/客户端解析失败",而配置本身看似正确。根因常是签名未及时更新(如记录变更后未重新签名、签名周期配置过短且未自动续签)。自动化续签要点:启用权威服务器的自动签名(automatic signing),设置合理的签名有效期与更新周期(如签名前再刷新),在记录变更时触发重新签名,并确保密钥滚动(KSK/ZSK 轮换)与 DS 更新流程自动化。监控要点:监控 RRSIG 到期时间、签名覆盖率、验证成功率、SERVFAIL 比例,对即将过期的签名提前告警,并监控 KSK/ZSK 轮换是否成功。

DNSSEC 故障常是"时间问题":签名过期导致验证失败。解决靠"自动续签 + 过期监控",把签名生命周期纳入自动化,避免人为漏签。

#
★★★

9. Kubernetes Service、EndpointSlice 与 CoreDNS 记录如何把服务名映射到后端 Pod?

请说明 Kubernetes 中 Service、EndpointSlice 与 CoreDNS 记录如何把服务名映射到后端 Pod?

  • Service 与 EndpointSlice
  • CoreDNS 的 A/SRV 记录
  • 服务名到 Pod IP 的解析

Kubernetes 中:Service 定义了稳定的服务入口(ClusterIP/名称),其 selector 选择一组 Pod;EndpointSlice 控制器根据 Service 的 selector 生成 EndpointSlice,记录后端 Pod 的 IP 与端口。CoreDNS 是集群内 DNS,为 Service 生成 DNS 记录:<service>.<namespace>.svc.cluster.local 的 A 记录指向 ClusterIP(或 headless 时指向各 Pod IP),SRV 记录指向端口与目标。当客户端解析服务名时,CoreDNS 返回 ClusterIP(或 headless 的 Pod IP 列表),客户端再把流量经 Service 转发到后端 Pod(ClusterIP 由 kube-proxy 转发到 EndpointSlice 中的 Pod)。因此服务名到 Pod 的映射链是"Service→EndpointSlice→Pod IP",CoreDNS 提供 A/SRV 记录把服务名映射到 ClusterIP 或 Pod IP。

Service 是抽象入口,EndpointSlice 是"后端 Pod 列表"(数据来源),CoreDNS 是"DNS 视图"。headless service 直接返回 Pod IP,普通 service 返回 ClusterIP 再由 kube-proxy 转发。

#
★★

10. DNS 缓存投毒攻击(Kaminsky)的根本原因是什么,源端口随机化与 0x20 编码如何缓解?

请说明 DNS 缓存投毒攻击(Kaminsky 攻击)的根本原因,以及源端口随机化与 0x20 编码如何缓解?

  • Kaminsky 攻击与投毒机制
  • 事务 ID 与源端口随机化
  • 0x20 编码的缓解

Kaminsky 攻击的根本原因是 DNS 查询的响应验证过于宽松:历史上递归器只验证事务 ID(16 位)和源地址,攻击者伪造响应,通过猜测事务 ID 抢先注入伪造的权威记录,使递归器缓存投毒(把域名指向攻击者地址)。攻击者可快速迭代查询不存在的子域名,提高猜中概率。缓解:源端口随机化——每次查询使用随机源端口(增加熵,从 16 位 ID 扩展到 16+端口位),攻击者更难猜中完整(ID+端口+地址)组合;0x20 编码——对查询名随机混合大小写(如 ExAmPle.com),伪造响应必须精确匹配大小写,攻击者无法预知大小写组合,增加伪造难度。两者都是"增加可预测性难度"。

根因是"响应验证熵不足"。源端口随机化与 0x20 编码都通过扩大"不可预测的位"来提升伪造难度,是缓解而非根治。

#
★★

11. DNS 缓存过期后客户端仍能解析可能源于 ndots、search domain 与 negative cache TTL 组合,如何系统排查?

请说明 DNS 缓存过期后客户端仍能解析可能源于 ndots、search domain 与 negative cache TTL 的组合,并给出系统排查方法?

  • ndots 与 search domain 的解析顺序
  • negative cache TTL 与缓存
  • 系统排查

客户端解析仍能查到旧地址,可能源于:1) ndots 决定查询名何时先按全限定名解析——ndots 较高时,非全限定名会先尝试组合 search domain,可能命中旧的缓存或错误域名;2) search domain 的拼接使查询走了不同路径,命中缓存或权威的不同结果;3) negative cache TTL 使"不存在"的负缓存延长,导致新增记录迟迟不生效。排查时:用 dig/nslookup 分别查全限定名与非限定名,观察 ndots 与 search 的组合;检查本地 resolver 缓存(systemd-resolved/dnsmasq)与负缓存 TTL;用 dig +trace 看权威返回,确认是否被上层缓存遮蔽;刷新 resolver 缓存并核对 ndots 配置(如 /etc/resolv.conf 的 options ndots)与 search 列表。

这类"缓存过期仍解析到旧值"多因"解析路径被 ndots+search 改变"或"负缓存延长"。系统排查需分离"本地缓存、resolver 缓存、权威"三层,并核对 ndots/search 配置。

#
★★

12. 客户端缓存超过权威 TTL 会怎样影响故障摘除,连接池复用为何会进一步延迟切换?

请说明客户端缓存超过权威 TTL 会如何影响故障摘除,以及连接池复用为何会进一步延迟切换?

  • 客户端缓存与权威 TTL 的关系
  • 故障摘除的延迟
  • 连接池复用与切换延迟

权威 TTL 决定 DNS 记录可被缓存多久,客户端缓存超过权威 TTL 时,客户端在 TTL 内持续使用旧地址,即使权威已摘除故障节点,客户端仍会访问旧 IP,导致故障摘除延迟(最长可达 TTL 时长)。连接池复用进一步加剧:即使客户端缓存更新了新地址,应用层已建立的连接池(如 HTTP 连接池、gRPC channel)仍复用旧连接,不会立即断开重建,只有当旧连接失败或池刷新时才切换,因此切换延迟在 DNS TTL 之上又叠加了连接池生命周期。latency 表现为"故障摘除到真正切换"的延迟=缓存 TTL + 连接池复用时间。

TTL 决定"多久发现新地址",连接池决定"多久用新地址"。要加快摘除,需缩短 TTL、客户端主动刷新、连接池失败检测与重连机制。

#
★★

13. 服务网格(Istio/Linkerd)中的 EDS(Endpoint Discovery Service)相比传统 DNS 轮询在故障检测时延上的优势来自哪里?

请说明服务网格(Istio/Linkerd)中的 EDS(端点发现服务)相比传统 DNS 轮询在故障检测时延上的优势来自哪里?

  • EDS(xDS 的 EDS)与 DNS 轮询
  • 主动推送 vs 轮询
  • 故障检测时延

传统 DNS 轮询依赖客户端周期查询 DNS 获取后端列表,TTL 内缓存的旧地址使故障检测延迟较大(至少一个 TTL)。服务网格的 EDS(Endpoint Discovery Service,属于 xDS 协议)由控制面(如 Istio 的 Pilot / Linkerd 的控制面)主动监测端点的健康状态,通过长连接(xDS 流)及时把端点变更(增删、健康与否)推送给数据面(Envoy/Linkerd 代理),无需等待 TTL。优势在于:控制面实时感知健康状态并主动推送,端点的故障/恢复被即刻反映到负载均衡器,检测时延从"秒级 TTL"降到"毫秒级推送",且数据面能基于主动健康检查(如 Envoy 的 EDS + 主动探测)快速剔除故障端点。

核心是"推送 vs 轮询":EDS 靠控制面主动推送 + 探活,避免 DNS 的 TTL 缓存延迟,实现近实时故障摘除。这是服务网格比 DNS 更快的根本原因。

#
★★

14. 排查间歇性 SERVFAIL 时,如何检查 DNSSEC 时钟、EDNS 大包分片、上游超时与 lame delegation?

请说明排查间歇性 SERVFAIL 时,如何检查 DNSSEC 时钟、EDNS 大包分片、上游超时与 lame delegation?

  • DNSSEC 时钟一致性与签名
  • EDNS 大包与分片
  • 上游超时与 lame delegation

间歇性 SERVFAIL 排查:1) DNSSEC 时钟——验证签名依赖系统时钟,若权威/验证器时钟偏差或签名过期,RRSIG 验证失败返回 SERVFAIL,检查时钟同步与签名有效期;2) EDNS 大包分片——启用 EDNS 后响应可达 4000+ 字节,若路径 MTU 限制导致 UDP 分片被丢弃,响应丢失→SERVFAIL,用 EDNS 小响应或 TCP 兜底、检查 MTU;3) 上游超时——递归器向上游/权威查询超时(网络抖动、权威慢)会返回 SERVFAIL,观察上游响应时间与重试;4) lame delegation——权威 NS 指向不负责该域名的服务器(配置错误),查询得不到正确应答→SERVFAIL,用 dig +trace 检查 NS 的权威性。逐一排查可定位 SERVFAIL 根因。

SERVFAIL 是"解析失败"的通用信号,根因在签名/时钟、EDNS 传输、上游稳定性、授权配置四类。系统性检查这四层可快速定位间歇性失败。

#
★★

15. 为什么 gRPC 的 service config + DNS resolver 在 K8s 集群内仍需要 headless service + Endpoints,而非 ClusterIP?

请说明为何 gRPC 的 service config + DNS resolver 在 K8s 集群内仍需要 headless service + Endpoints,而非使用 ClusterIP?

  • gRPC 的 DNS resolver 与负载均衡
  • ClusterIP 无法逐 Pod 感知
  • headless service 返回 Pod IP

gRPC 的负载均衡是客户端侧(client-side load balancing)的:客户端通过 DNS resolver 解析到多个后端地址,再在客户端做 Subchannel 级负载均衡。若使用 ClusterIP Service,DNS 只返回一个 ClusterIP,由 kube-proxy 做四层转发,客户端无法感知/直接连接各 Pod,也无法做 gRPC 的客户端级均衡与健康感知。而 headless service(ClusterIP: None)不生成 ClusterIP,CoreDNS 直接返回所有后端 Pod 的 IP,配合 Endpoints/EndpointSlice 反映 Pod 列表,gRPC 客户端便能解析到全部 Pod IP,在客户端做均衡、故障检测与重连。因此 gRPC 需要 headless service + Endpoints 提供"真实 Pod 列表",而非 ClusterIP 的单一虚拟地址。

gRPC 要"客户端看到全部后端",ClusterIP 提供"单一虚拟入口"(由 kube-proxy 隐藏后端),headless 提供"全部 Pod IP"。这是 gRPC 客户端负载均衡对 DNS 模型的要求。

#
★★

16. 服务发现与配置中心(Apollo/Nacos/ConfigMap)在推送机制上分别为长轮询、watch 与 HTTP poll,QoS 与一致性差距如何?

请说明服务发现与配置中心(Apollo/Nacos/ConfigMap)在推送机制上分别为长轮询、watch 与 HTTP poll,并分析其 QoS 与一致性差距?

  • 长轮询、watch、HTTP poll 三种机制
  • 一致性(强一致/最终一致)
  • QoS 与实时性

Apollo 配置中心用长轮询:客户端发起 HTTP 请求,服务端在配置变更或有超时时才返回,实现准实时推送,延迟低且与 HTTP 兼容。Nacos 用 watch(长连接/通知)机制:客户端订阅服务,服务端变更时主动通知,实时性好,且 Nacos 支持集群下的强一致或最终一致(取决于模式)。Kubernetes ConfigMap 用 HTTP poll(watch 本身是 etcd 的 watch,但 ConfigMap 更新靠 kubelet 周期性轮询或 watch):ConfigMap 更新存在传播延迟,Pod 内生效需重新挂载/重启,属最终一致。差距:实时性(长轮询/watch 高,poll 低)、一致性(Nacos 可达强一致,Apollo 长轮询基本实时但非强同步,ConfigMap 最终一致且延迟大)、QoS(长轮询需合理超时与重连,watch 需长连接保活,poll 简单但延迟高)。

三种机制是"推送实时性与实现复杂度"的权衡:长轮询/watch 实时但需连接管理,poll 简单但延迟高。一致性上 watch 可强一致,poll 最终一致。

#
★★

17. SRV 记录的 priority、weight、port 如何驱动客户端选择,失败重试应避免什么偏差?

请说明 SRV 记录的 priority、weight、port 字段如何驱动客户端选择,以及失败重试应避免什么偏差?

  • SRV 的 priority/weight/port
  • 目标选择与权重
  • 失败重试的偏差

SRV 记录包含 priority、weight、port 和目标主机:priority 决定首选顺序(数字小者优先,同 priority 组内再按 weight 选择);weight 在同一 priority 内按权重随机/加权选择目标(weight 越大被选中概率越高);port 是服务端口。客户端先按 priority 分组,优先使用 priority 最小的组,组内按 weight 加权随机选取目标。失败重试时应避免的偏差:若重试总是从"列表头部"开始,会因头部目标总是先被选中而负载不均,且对已失败目标反复重试形成"放大效应";应随机化重试起点、对失败目标做退避、避免固定顺序偏差,并轮换。

priority 分层、weight 加权、port 指定端口。重试要避免"固定顺序导致头部偏爱"与"失败目标反复命中"的偏差,需随机化+退避。

#
★★

18. Kubernetes 中 Pod readiness probe 与 EndpointSlice controller 的 readiness gating 联动如何避免流量进入未就绪 Pod?

请说明 Kubernetes 中 Pod readiness probe 与 EndpointSlice controller 的 readiness gating 联动如何避免流量进入未就绪 Pod?

  • readiness probe 与就绪状态
  • EndpointSlice 的 readiness 条件
  • Service 流量与就绪 Pod

Kubernetes 中 Pod 的 readiness probe 定期检查应用是否就绪(能接收流量),就绪时 Pod 的 ready 状态为 true。EndpointSlice controller 根据 Pod 的 ready 状态生成 EndpointSlice,其中就绪 Pod 的端点被标记为 ready(serving),未就绪 Pod 的端点标记为 not-ready。Service 的流量(kube-proxy/负载均衡)只送往 ready 状态的端点,未就绪 Pod 被排除在服务后端之外,从而避免流量进入未就绪 Pod。readiness gating(如 EndpointSlice 的 serving 条件)确保只有通过 readiness probe 的 Pod 才接受流量,未就绪(如启动中、探活失败)的 Pod 不接收流量,但这不影响其接受流量外的其他功能。

"readiness probe 决定 Pod 就绪,EndpointSlice 据就绪标记端点,Service 只转发到就绪端点"形成闭环。这是避免流量进入未就绪 Pod 的机制。

#
★★

19. 客户端负载均衡策略(random、round-robin、least-requests、power-of-two-choices)在重尾延迟下表现差异如何?

请说明客户端负载均衡策略 random、round-robin、least-requests、power-of-two-choices 在重尾延迟下的表现差异?

  • 各负载均衡策略
  • 重尾延迟与负载均衡
  • 策略的表现差异

random 与 round-robin 是"无状态"的公平轮询/随机,不考虑后端负载,在重尾延迟场景下,慢请求或慢后端会造成"堵车"(如某后端因慢请求积压,但新请求仍被均匀分发),无法感知并规避慢后端,整体延迟差。least-requests 是"感知负载"的:把新请求发给当前在途请求最少的后端,能避免把请求发给已积压的后端,在重尾场景下更优,但需维护在途计数,且可能被一个慢请求卡住计数。power-of-two-choices 是折中:随机取两个后端,选其中负载(在途请求等)较小的那个,兼具随机性的低开销与"感知负载"的均衡,在重尾延迟下显著优于随机/轮询,且比全局 least-requests 开销小、鲁棒性好。因此重尾下表现:power-of-two-choices/least-requests 优于 random/round-robin。

重尾延迟下"感知负载"的均衡策略(least-requests、power-of-two-choices)能规避慢后端,比"无状态"的 random/round-robin 更优。power-of-two-choices 以低开销达到接近最优的均衡。

#
★★

20. CNAME、DNAME、ALIAS/ANAME 的语义有何不同,zone apex 为什么不能简单放置 CNAME?

请说明 CNAME、DNAME、ALIAS/ANAME 的语义差异,以及 zone apex(根)为什么不能简单放置 CNAME?

  • CNAME、DNAME、ALIAS/ANAME 语义
  • CNAME 与共存记录冲突
  • zone apex 的 CNAME 限制

CNAME 把"一个名称"别名指向另一个名称,且该名称不能有任何其他记录(除 DNSSEC 相关),语义是"完全别名"。DNAME 把"一个子树"的所有名称都别名到另一个子树(如 example.com 子树全部重定向),作用于后代域名。ALIAS/ANAME 是厂商扩展:在 zone apex 提供"别名"语义,但 DNS 服务器会解析目标并返回实际的 A/AAAA 记录,因此 apex 仍可保留其他记录(如 MX、NS、SOA)。zone apex(根)不能放 CNAME 的原因是:CNAME 不允许与任何其他记录共存,而 apex 必须有 SOA、NS 等记录,且 CNAME 会与 MX/NS 等记录冲突,故 apex 无法用 CNAME。ALIAS/ANAME 专门解决 apex 的别名需求。

CNAME 是"单名全别名、不容共存",DNAME 是"子树别名",ALIAS/ANAME 是"apex 可用的别名"。apex 因需 SOA/NS 共存而不能用 CNAME。

#
★★

21. 为什么 zone apex 不能用 CNAME 与 MX/NS 冲突,ALIAS/ANAME 实现上是 A 记录拼接还是 302 重定向?

请说明 zone apex 为何不能用 CNAME(与 MX/NS 冲突),以及 ALIAS/ANAME 实现上是 A 记录拼接还是 302 重定向?

  • apex 与 CNAME 的冲突
  • ALIAS/ANAME 的实现方式
  • 解析时拼接 vs 重定向

zone apex 承载 SOA、NS 等权威记录,而 CNAME 的规范要求"一个名称若为 CNAME 则不能有其他任何记录",因此 apex 放 CNAME 会与 SOA/NS/MX 等冲突,违反 DNS 规范,导致解析异常。ALIAS/ANAME 的实现是"A 记录拼接"而非"302 重定向":ALIAS/ANAME 记录在权威服务器侧被解析(权威服务器替客户端查询目标地址),把目标的 A/AAAA 记录作为本名称的 A/AAAA 返回给客户端,客户端看到的是普通 A/AAAA 记录,无需再次跟随别名。它不是 HTTP 级的 302 重定向(DNS 无重定向概念),而是"服务器侧展开目标记录并拼接返回"。

CNAME 与共存记录冲突是规范限制,ALIAS/ANAME 用"服务器侧解析目标并返回 A/AAAA"实现 apex 别名,客户端无感知(非 302)。

#

22. Consul、etcd、ZooKeeper 作为服务注册中心在一致性模型(CP/AP)与 watch 语义上的取舍是什么?

请说明 Consul、etcd、ZooKeeper 作为服务注册中心在一致性模型(CP/AP)与 watch 语义上的取舍?

  • 一致性模型 CP/AP
  • 各注册中心的实现
  • watch 语义

ZooKeeper 是 CP 模型:基于 ZAB 协议,保证顺序一致性与强一致,写操作需多数派确认,分区时可能拒绝写(牺牲可用性保证一致性),watch 是一次性通知(客户端需重新注册)。etcd 也是 CP:基于 Raft,强一致,支持 watch 流式推送(长时间推送变更),适合作为分布式协调的强一致数据源。Consul 默认 CP(基于 Raft,服务注册强一致),但可配置为 AP 模式(健康检查基于 gossip,不支持强一致,分区时仍可用)。取舍:CP 型(ZK/etcd/Consul 默认)保证一致但分区时可用性下降;AP 型(Consul AP)保证可用但可能有分叉。watch 语义上,ZK 是一次性 watch,etcd/Consul 支持流式 watch,前者实现简单、后者实时性更好。

一致性是 CAP 的取舍:CP 牺牲分区可用性,AP 牺牲一致性。watch 语义(一次性 vs 流式)影响客户端实时性与实现复杂度。

#

23. 在双注册中心(consul + nacos)环境中,跨中心数据同步通过 xDS 还是自研 replication,哪种场景更易出现脑裂?

请说明双注册中心(consul + nacos)环境中跨中心数据同步通过 xDS 还是自研 replication,哪种场景更易出现脑裂?

  • 双注册中心的数据同步
  • xDS 与自研 replication
  • 脑裂风险

双注册中心(consul + nacos)跨中心数据同步有两种方式:一是用 xDS(服务网格的标准同步协议)把服务发现数据统一分发/同步,二是自研 replication(自建复制逻辑把注册数据在两个中心间同步)。xDS 是标准化的控制面数据分发协议,适合服务网格场景,同构、可扩展;自研 replication 灵活但需自行处理一致性、冲突与故障。脑裂风险:当两个中心的网络分区(partition)时,若用自研 replication(两端各自写入、异步复制),两端可能各自接受变更并产生不一致数据,形成"脑裂"(两端数据分叉);若用 xDS 由单一控制面统一分发,可避免双写分叉,但若控制面本身分区也可能分叉。更易脑裂的场景是"双写 + 异步复制"(自研 replication 或双主),因为分区时两端各自接受写入,数据无法收敛;而 xDS 单一数据源在分区时通常拒绝写入或保持统一,脑裂风险较低。

脑裂源于"双写 + 异步复制"在分区时无法收敛。xDS 单一数据源 + 协调器能降低脑裂,但引入控制面单点;自研复制需处理冲突与一致性。

#

24. 服务发现返回的 endpoint 元数据(zone、region、version)如何被客户端纳入负载均衡权重,蓝绿发布与灰度发布怎么映射?

请说明服务发现返回的 endpoint 元数据(zone、region、version)如何被客户端纳入负载均衡权重,以及蓝绿发布与灰度发布如何映射?

  • endpoint 元数据与负载均衡权重
  • 区域感知(zone/region)路由
  • 蓝绿与灰度发布映射

服务发现返回的 endpoint 元数据(zone、region、version)可被客户端纳入负载均衡:客户端根据 zone/region 做区域感知(优先本地 region/zone,避免跨区延迟),根据 version 做版本感知路由,按元数据匹配来调整权重(如优先同一 region 的权重大,新 version 的权重按灰度比例调整)。蓝绿发布映射:两个版本(蓝/绿)作为两个独立 endpoint 集合,通过负载均衡权重一次性切换(如蓝 100% 切到绿 100%),或按版本路由把流量全量切到新版本,实现快速回滚。灰度发布映射:按版本把流量按比例分配(如新版本 10%、旧版本 90%),通过动态调整 endpoint 权重或按用户/元数据分流(如按 header、用户 ID),逐步放大新版本比例,配合监控决定继续或回滚。

元数据(zone/region/version)让负载均衡从"无差别轮询"升级为"区域感知 + 版本路由"。蓝绿是全量切换、灰度是渐进放量,都通过权重/路由映射实现。