← 中文资源

简体中文版本

用 DNS 切换到备用区域

创建带健康检查的主备记录,通过临时禁用健康检查验证切换,并充分考虑 TTL 带来的延迟。

阅读英文原文

概述

基于健康检查的 DNS 可以在没有前置负载均衡的情况下切换端点,适合区域级故障转移,逻辑也容易理解。但它很慢:健康检查需要连续失败才会标记端点不可用,解析器会按 TTL 缓存旧答案,已建立的连接完全不受 DNS 影响。因此应准备分钟级的恢复预期,而不是秒级,并且确认备用区域能够承接全部流量后再依赖它。切换流程必须经过验证,未演练过的故障转移往往在最糟糕的时刻失效。

步骤

  1. 为主端点创建健康检查:
aws route53 create-health-check \
  --caller-reference payments-primary-$(date +%s) \
  --health-check-config Type=HTTPS,ResourcePath=/healthz,FullyQualifiedDomainName=primary.example.com,RequestInterval=30,FailureThreshold=3
  1. 创建引用健康检查的主备记录:
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "api.example.com",
        "Type": "A",
        "SetIdentifier": "primary",
        "Failover": "PRIMARY",
        "HealthCheckId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
        "AliasTarget": {
          "HostedZoneId": "Z1D633PJN98FT9",
          "DNSName": "primary-lb.eu-west-1.elb.amazonaws.com",
          "EvaluateTargetHealth": true
        }
      }
    },
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "api.example.com",
        "Type": "A",
        "SetIdentifier": "secondary",
        "Failover": "SECONDARY",
        "AliasTarget": {
          "HostedZoneId": "Z1D633PJN98FT9",
          "DNSName": "secondary-lb.eu-west-1.elb.amazonaws.com",
          "EvaluateTargetHealth": true
        }
      }
    }
  ]
}
  1. 临时禁用健康检查以验证切换:
aws route53 update-health-check \
  --health-check-id a1b2c3d4-5678-90ab-cdef-1234567890ab --disabled
sleep 120
dig +short api.example.com
  1. 确认 TTL 与解析结果:
dig api.example.com | grep -A 2 'ANSWER SECTION'

验证

禁用健康检查后约两分钟,解析结果应变为备用地址;重新启用后应恢复为主地址,说明可以双向切换。记录的 TTL 必须与恢复目标匹配,过长会让故障转移形同虚设。还需确认健康检查的状态历史,避免检查本身配置错误却始终返回健康。

注意事项

  • DNS 故障转移本质上较慢,无法满足对已有连接的秒级恢复。
  • 单一路径的健康检查可能在应用大部分功能仍正常时判定失败。
  • 备用区域需要预热缓存、同步密钥,并明确数据库的读写模式。
  • 计划内维护前应提前降低 TTL,避免解析器缓存造成延迟。
  • 健康检查本身也要监控,否则会带来“有保护”的错觉。