$upstream_connect_time记录nginx与upstream完成tcp握手耗时(秒,毫秒精度),包含dns解析和tcp握手时间,不包含ssl握手与请求处理;空值表示未走upstream,-表示连接失败,keepalive复用时接近0。

直接看日志里 $upstream_connect_time 占 $request_time 的比例——超过 20% 且 $upstream_header_time 同步升高,基本就能锁定是 DNS 解析拖慢了代理连接。
盯紧 Nginx 访问日志里的三个时间字段
默认日志不暴露 DNS 耗时,但 $upstream_connect_time 实际包含 DNS 解析 + TCP 握手。如果它持续高于 100ms(尤其后端 IP 固定、网络无抖动),DNS 就是头号嫌疑对象。
- $upstream_connect_time 明显偏高,而 $upstream_response_time − $upstream_header_time 很小 → 首字节慢,卡在建连阶段
- $upstream_header_time 和 $upstream_response_time 同步拉长、差值窄 → 不是后端处理慢,也不是响应体传输慢
- 计算比值:$upstream_connect_time / $request_time > 0.2 → DNS 开销已成瓶颈
翻 error.log 找 DNS 失效的“暗号”
Nginx 很少直说“DNS 失败”,而是用间接报错暴露问题:
- resolver timeout、no resolver defined、could not be resolved → resolver 配置无效或不可达
- host not found in upstream → reload 时域名就解析失败(配置加载阶段问题)
- no peer_addr 或 getaddrinfo() failed → 连接目标地址都没拿到,根源大概率是 DNS 没返回 IP
验证 resolver 是否真在干活
很多人写了 resolver 却没生效,因为作用域错、被绕过,或根本没触发动态解析:
- 确认 resolver 写在 http 块顶层(不是 stream、不是 server 里漏配),且 proxy_pass 使用变量(如
set $backend "api.example.com"; proxy_pass http://$backend;),硬写域名会跳过运行时解析 - 执行
dig api.example.com @8.8.8.8 +short和nslookup api.example.com 127.0.0.1对比耗时,看是不是你配的 DNS 本身延迟高或不稳定 - 检查是否误用了容器内 DNS(如 127.0.0.11)或本地回环(127.0.0.1)——它们转发链路长、无缓存,极易超时
临时绕过 DNS 快速验证
不改代码、不调参数,三步确认是不是 DNS 拖垮了连接:
- 把 upstream 中的域名换成对应 IP(如
server 10.20.30.40:8080;),reload Nginx - 观察 502 是否消失、$upstream_connect_time 是否骤降
- 若恢复正常,再在 /etc/hosts 加一行映射(
10.20.30.40 api.example.com),既能保留域名语义,又规避运行时解析











