#!/usr/bin/env bash
# ==============================================================================
# 脚本名称: check_dns_timeout.sh
# 功能描述: 自动化诊断本地 resolv.conf 中存在的 DNS 超时死节点及配置隐患 (纯只读)
# 使用方式: 在目标 Linux 宿主机直接执行
# ==============================================================================
set -o pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PLAIN='\033[0m'
echo -e "${BLUE}================================================================${PLAIN}"
echo -e "${BLUE} 系统 DNS 解析链路 5秒隐形卡顿自动化诊断脚本 ${PLAIN}"
echo -e "${BLUE}================================================================${PLAIN}"
# 1. 提取当前系统配置的 Nameserver
DNS_SERVERS=$(grep -v "^[[:space:]]*#" /etc/resolv.conf 2>/dev/null | grep "^nameserver" | awk '{print $2}')
if [ -z "$DNS_SERVERS" ]; then
echo -e "${RED}[FATAL] /etc/resolv.conf 中未配置任何有效的 nameserver。${PLAIN}"
exit 1
fi
echo -e "\n${YELLOW}[1/2] 正在提取并逐一探测本地 DNS 节点的连通性与响应耗时...${PLAIN}"
BAD_DNS_FOUND=0
INDEX=1
for dns in $DNS_SERVERS; do
echo -e " -> [节点 $INDEX] 目标 DNS IP: ${YELLOW}${dns}${PLAIN}"
# 记录探测起始时间
START_TIME=$(date +%s)
# 发起真实 DNS 解析请求,强制 1 秒超时
if dig @"$dns" www.baidu.com +time=1 +tries=1 >/dev/null 2>&1; then
END_TIME=$(date +%s)
COST=$((END_TIME - START_TIME))
echo -e " 连通状态: ${GREEN}OK (响应耗时 < 1s)${PLAIN}"
else
echo -e " 连通状态: ${RED}Timeout / Refused${PLAIN}"
echo -e " ${RED}[ALERT] 发现失效 DNS 节点!该节点将强制引发 Linux 底层每次解析 5 秒的 poll 阻塞卡顿。${PLAIN}"
BAD_DNS_FOUND=1
fi
((INDEX++))
done
# 2. 检查 resolv.conf 高级配置优化参数
echo -e "\n${YELLOW}[2/2] 检查 DNS 底层超时优化参数 (options)...${PLAIN}"
OPTIONS_LINE=$(grep -v "^[[:space:]]*#" /etc/resolv.conf 2>/dev/null | grep "^options")
if echo "$OPTIONS_LINE" | grep -q "timeout:"; then
TIMEOUT_VAL=$(echo "$OPTIONS_LINE" | grep -o 'timeout:[0-9]*' | cut -d':' -f2)
if [ "$TIMEOUT_VAL" -le 2 ]; then
echo -e " -> ${GREEN}[OK] 已配置短超时优化 (timeout:${TIMEOUT_VAL}),有效降低单点失效带来的延迟惩罚。${PLAIN}"
else
echo -e " -> ${YELLOW}[WARN] 存在 timeout 配置,但设定数值偏大 (${TIMEOUT_VAL}s),仍会引发明显卡顿。${PLAIN}"
fi
else
echo -e " -> ${RED}[WARN] 未配置 options timeout 参数!若遭遇首选节点失效,系统将强制等待默认的 5 秒超时。${PLAIN}"
echo -e " -> ${GREEN}[优化建议] 建议在 /etc/resolv.conf 尾部追加配置: options timeout:1 attempts:1${PLAIN}"
fi
# 3. 输出综合诊断结论
echo -e "\n${BLUE}----------------------------------------------------------------${PLAIN}"
if [ "$BAD_DNS_FOUND" -eq 1 ]; then
echo -e "${RED}[最终诊断] 明确存在失效的 DNS 节点!这是引发业务接口恒定 5 秒隐形阻塞的直接根源。${PLAIN}"
echo -e "${YELLOW}处置建议: 请立即编辑 /etc/resolv.conf,注释或移除失效的 nameserver 记录。${PLAIN}"
else
echo -e "${GREEN}[最终诊断] 本地 DNS 解析链路健康,未发现引发 5 秒底层阻塞的基础设施隐患。${PLAIN}"
echo -e "${GREEN}排障指引: 若接口依然存在卡顿,请使用 strace -f -p <PID> -T 检查是否阻塞在应用层的网络 I/O (如 recvfrom 等待下游返回)。${PLAIN}"
fi
echo -e "${BLUE}================================================================${PLAIN}"