AI辅助声明 :本文内容经过AI辅助整理和优化,结合2026年最新DNS故障排查实践进行更新。
更新说明 :补充了最新的DNS故障排查工具和方法。
引言 在运维生产环境时,域名解析问题是最常见的故障类型之一。当用户反馈”网站时好时坏”或”部分地区无法访问”时,往往与 DNS 配置有关。本文以真实的排查案例为基础,详细介绍 DNS 多 IP 绑定场景下的问题定位方法和解决方案。
问题场景描述 故障现象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ┌─────────────────────────────────────────────────────────────────────┐ │ 故障现象:域名访问时好时坏 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 用户反馈: │ │ ├── 通过域名访问网站,有时正常,有时失败 │ │ ├── 浏览器显示 "无法连接到服务器" 或 "连接超时" │ │ └── 直接访问 IP 地址没有问题 │ │ │ │ 初步判断: │ │ ┌──────────────┐ DNS 轮询 ┌──────────────┐ │ │ │ 用户浏览器 │ ─────────────► │ DNS 服务器 │ │ │ └──────────────┘ └───────┬──────┘ │ │ │ │ │ 返回多个 A 记录 │ │ │ ▼ │ │ ┌───────────────────────┼───────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐│ │ │ 服务器 A │ │ 服务器 B │ │ 服务器 C ││ │ │ 192.0.2.1│ │192.0.2.2 │ │192.0.2.3 ││ │ └────┬─────┘ └────┬─────┘ └────┬─────┘│ │ │ │ │ │ │ └─────────────────────┴─────────────────────┘ │ │ │ │ │ 其中服务器 B 已下线或故障 │ │ │ │ │ 用户访问失败 │ │ │ └─────────────────────────────────────────────────────────────────────┘
DNS 基础概念 DNS 记录类型
记录类型
说明
示例
A
将域名指向 IPv4 地址
example.com. A 192.0.2.1
AAAA
将域名指向 IPv6 地址
example.com. AAAA 2001:db8::1
CNAME
域名别名
www.example.com. CNAME example.com.
MX
邮件交换记录
example.com. MX 10 mail.example.com.
TXT
文本记录
用于验证、SPF 等
NS
域名服务器记录
指定 DNS 服务器
多 A 记录负载均衡 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ┌─────────────────────────────────────────────────────────────────────┐ │ DNS 轮询负载均衡原理 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ DNS 配置: │ │ │ │ example.com. 300 IN A 192.0.2.1 (服务器 1) │ │ example.com. 300 IN A 192.0.2.2 (服务器 2) │ │ example.com. 300 IN A 192.0.2.3 (服务器 3) │ │ │ │ 轮询策略: │ │ │ │ 第一次查询 ──► 返回 [192.0.2.1, 192.0.2.2, 192.0.2.3] │ │ 第二次查询 ──► 返回 [192.0.2.2, 192.0.2.3, 192.0.2.1] │ │ 第三次查询 ──► 返回 [192.0.2.3, 192.0.2.1, 192.0.2.2] │ │ │ │ 客户端行为: │ │ ├── 大多数客户端会尝试第一个 IP │ │ ├── 失败后尝试第二个 IP │ │ └── 所有 IP 失败后报告错误 │ │ │ │ 问题场景: │ │ └── 如果其中某个 IP 对应的服务器故障,部分用户会访问失败 │ │ │ └─────────────────────────────────────────────────────────────────────┘
问题排查流程 第一步:确认 DNS 解析结果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 dig example.com A dig @8.8.8.8 example.com A dig @1.1.1.1 example.com A dig +trace example.com nslookup example.com nslookup example.com 8.8.8.8 host example.com host -a example.com
第二步:验证各 IP 的连通性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 for ip in 192.0.2.1 192.0.2.2 192.0.2.3; do echo "Testing $ip ..." ping -c 3 $ip done fping -c 3 192.0.2.1 192.0.2.2 192.0.2.3 for ip in 192.0.2.1 192.0.2.2 192.0.2.3; do echo "Testing HTTP on $ip ..." curl -I -H "Host: example.com" http://$ip / --connect-timeout 5 done
第三步:Nginx 配置检查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 server { listen 80 ; listen 192.0.2.1:80 ; listen 192.0.2.2:80 ; listen 192.0.2.3:80 ; server_name example.com www.example.com; location / { root /var/www/html; index index.html; } } server { listen 80 default_server; server_name _; location / { root /var/www/html; index index.html; } }
完整排查案例 案例背景 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ┌─────────────────────────────────────────────────────────────────────┐ │ 案例:渠道接入时的域名问题 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 场景: │ │ - 游戏接入新渠道,渠道方提供域名指向我方服务器 │ │ - 渠道方域名配置:game.channel.com ──► 我方 IP 列表 │ │ - 用户通过渠道下载游戏,游戏内使用渠道域名连接服务器 │ │ │ │ 故障现象: │ │ - 部分用户反馈游戏登录失败 │ │ - 有时可以登录,有时失败 │ │ - 问题随机出现,难以复现 │ │ │ └─────────────────────────────────────────────────────────────────────┘
排查步骤详解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 dig game.channel.com A +short echo "=== 测试 IP 连通性 ===" for ip in 203.0.113.10 203.0.113.11 203.0.113.12; do echo -n "Testing $ip : " if ping -c 1 -W 2 $ip > /dev/null 2>&1; then echo "OK" else echo "FAILED" fi done echo "=== 测试 HTTP 服务 ===" for ip in 203.0.113.10 203.0.113.11 203.0.113.12; do echo -n "Testing HTTP on $ip : " response=$(curl -s -o /dev/null -w "%{http_code}" \ -H "Host: game.channel.com" \ --connect-timeout 5 \ http://$ip /health 2>/dev/null) echo "HTTP $response " done echo "=== 检查本地监听端口 ===" ss -tlnp | grep :80 netstat -tlnp | grep :80 echo "=== Nginx 配置检查 ===" grep -r "listen" /etc/nginx/conf.d/ nginx -t
发现问题
解决方案 方案一:通知渠道方修改 DNS(推荐)
方案二:在 Nginx 中配置所有 IP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 upstream game_backend { server 192.168.1.10:8080 ; server 192.168.1.11:8080 ; } server { listen 203.0.113.10:80 ; listen 203.0.113.11:80 ; listen 203.0.113.12:80 ; server_name game.channel.com; location / { proxy_pass http://game_backend; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; } }
方案三:使用负载均衡器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ┌─────────────────────────────────────────────────────────────────────┐ │ 使用负载均衡器统一入口 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 架构改造: │ │ │ │ DNS 记录 │ │ game.channel.com ─────────────────────► 负载均衡器 IP │ │ │ │ │ ┌───────────────────────┼───────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐│ │ │ 服务器 1 │ │ 服务器 2 │ │ 服务器 3 ││ │ │192.168.1.│ │192.168.1.│ │192.168.1.││ │ └──────────┘ └──────────┘ └──────────┘│ │ │ │ 优势: │ │ ├── 统一入口,DNS 只配置一个 IP │ │ ├── 负载均衡器自动检测后端健康状态 │ │ └── 故障服务器自动摘除,用户无感知 │ │ │ │ 常用负载均衡器: │ │ ├── Nginx / OpenResty │ │ ├── HAProxy │ │ ├── LVS (Linux Virtual Server) │ │ └── 云厂商 SLB (阿里云、AWS ELB 等) │ │ │ └─────────────────────────────────────────────────────────────────────┘
DNS 健康检查机制 HTTP 健康检查脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #!/bin/bash DOMAIN="game.channel.com" TIMEOUT=5 ALERT_WEBHOOK="https://hooks.slack.com/services/xxx" IPS=$(dig +short $DOMAIN A) echo "=== DNS Health Check for $DOMAIN ===" echo "Time: $(date) " echo "" failed_ips=() for ip in $IPS ; do echo -n "Checking $ip ... " http_code=$(curl -s -o /dev/null -w "%{http_code}" \ --connect-timeout $TIMEOUT \ -H "Host: $DOMAIN " \ http://$ip /health 2>/dev/null) if [ "$http_code " = "200" ]; then echo "OK (HTTP 200)" else echo "FAILED (HTTP ${http_code:-timeout} )" failed_ips+=($ip ) fi done if [ ${#failed_ips[@]} -gt 0 ]; then message=" DNS Health Check Alert\nDomain: $DOMAIN \nFailed IPs: ${failed_ips[*]} \nTime: $(date) " curl -X POST -H 'Content-type: application/json' \ --data "{\"text\":\"$message \"}" \ $ALERT_WEBHOOK fi
自动故障转移 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 import dns.resolverimport requestsimport jsonclass DNSFailover : def __init__ (self, domain, health_endpoint="/health" ): self .domain = domain self .health_endpoint = health_endpoint self .healthy_ips = [] def get_dns_ips (self ): """获取 DNS 解析的所有 IP""" try : answers = dns.resolver.resolve(self .domain, 'A' ) return [str (rdata) for rdata in answers] except Exception as e: print (f"DNS query failed: {e} " ) return [] def check_ip_health (self, ip ): """检查单个 IP 的健康状态""" try : response = requests.get( f"http://{ip} {self.health_endpoint} " , headers={"Host" : self .domain}, timeout=5 ) return response.status_code == 200 except : return False def update_healthy_ips (self ): """更新健康 IP 列表""" all_ips = self .get_dns_ips() self .healthy_ips = [ip for ip in all_ips if self .check_ip_health(ip)] with open ('/etc/app/healthy_ips.json' , 'w' ) as f: json.dump({ 'domain' : self .domain, 'healthy_ips' : self .healthy_ips, 'all_ips' : all_ips }, f) return self .healthy_ips if __name__ == '__main__' : import schedule import time failover = DNSFailover('game.channel.com' ) schedule.every(30 ).seconds.do(failover.update_healthy_ips) while True : schedule.run_pending() time.sleep(1 )
预防措施与最佳实践 DNS 配置检查清单
检查项
说明
工具
A 记录数量
确认绑定的 IP 都是有效的
dig +short
IP 连通性
所有 IP 都能 ping 通
ping / fping
服务可用性
所有 IP 的 HTTP/HTTPS 服务正常
curl
SSL 证书
所有 IP 的证书配置正确
openssl s_client
TTL 设置
合理的 TTL 值便于故障转移
dig
推荐的 DNS 架构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ┌─────────────────────────────────────────────────────────────────────┐ │ 高可用 DNS 架构推荐 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 方案一:负载均衡器模式(推荐) │ │ │ │ DNS: example.com ──► 负载均衡器 VIP │ │ │ │ │ ┌───────────┼───────────┐ │ │ ▼ ▼ ▼ │ │ [Server 1] [Server 2] [Server 3] │ │ (Health Check 自动摘除故障节点) │ │ │ │ 优点: │ │ - 用户只需要配置一个 IP │ │ - 故障自动切换,对用户透明 │ │ - 支持加权负载均衡 │ │ │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 方案二:Anycast 模式(大型应用) │ │ │ │ DNS: example.com ──► Anycast IP │ │ │ │ │ ┌─────────────┼─────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ [POP 1] [POP 2] [POP 3] │ │ (北京) (上海) (广州) │ │ │ │ │ │ │ └─────────────┴─────────────┘ │ │ 后端服务器集群 │ │ │ │ 优点: │ │ - 用户访问最近的节点 │ │ - 单点故障自动切换 │ │ - 全球加速 │ │ │ └─────────────────────────────────────────────────────────────────────┘
TTL 设置建议
场景
建议 TTL
说明
稳定环境
3600s (1小时)
减少 DNS 查询压力
故障转移
60s (1分钟)
快速切换,但增加查询量
灰度发布
300s (5分钟)
平衡灵活性和性能
DDoS 应急
10s
快速切换到高防 IP
总结 DNS 域名解析问题的排查要点:
问题定位 :dig / nslookup 查询 DNS 记录,确认所有绑定的 IP
连通性测试 :使用 ping、curl 逐一测试每个 IP 的连通性和服务可用性
配置检查 :确认 Nginx/服务器监听所有需要的 IP 地址
根本解决 :
通知域名管理员移除失效 IP
或配置服务器监听所有绑定 IP
预防措施 :
使用负载均衡器统一入口
建立 DNS 健康检查机制
合理设置 TTL 值便于故障切换
监控告警 :建立自动化监控,及时发现 DNS 配置异常
通过系统化的排查流程和合理的架构设计,可以有效避免和解决 DNS 多 IP 绑定带来的访问不稳定问题。