核心是拆解链路时间切片:用自定义日志($request_time、$upstream_response_time等)区分Nginx开销、后端处理、网络传输与建连延迟,并辅以tcpdump抓包和curl直连对比验证瓶颈所在。

测试 proxy_pass 转发链路的响应延迟,核心是拆解整个链路的时间切片,而不是只看用户端总耗时。重点在于区分 Nginx 自身开销、后端处理时间、网络传输和连接建立等环节,才能准确定位瓶颈。
用自定义日志暴露关键延迟字段
在 http 块中定义带时间变量的日志格式,并在对应 server 或 location 中启用:
- $request_time:客户端视角总耗时(上传 + Nginx 处理 + 后端响应 + 下发),单位秒,反映真实用户体验
- $upstream_response_time:Nginx 发起请求到收完后端响应头的时间,精确反映后端服务真实处理延迟
- $upstream_header_time:Nginx 收到后端响应首字节的时间,比 response_time 更敏感,适合排查 TTFB 类问题
- $upstream_connect_time:包含 DNS 解析 + TCP 握手耗时,若该值异常高(如 >100ms),需怀疑 DNS 或网络层问题
示例配置:
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
抓包验证后端实际响应行为
仅靠日志不够,需用 tcpdump 确认后端是否真慢、还是 Nginx 误判:
- 在 Nginx 服务器上执行:tcpdump -i any port
-w backend.pcap - 对比 Nginx 日志中记录的 upstream_connect_time 起点,与抓包里 TCP SYN 时间;再比对收到第一个响应 TCP 包的时间,确认延迟是否真发生在后端处理或网络返回环节
- 若后端是流式输出(如 chunked),但两次数据包间隔超过 proxy_read_timeout,Nginx 会主动断连——此时抓包能看到 FIN 包,而服务端日志可能无报错
用 curl 直连对比,排除 Nginx 干扰
绕过 Nginx,直接访问后端服务,验证是否为代理层引入延迟:
- 执行:curl -w "@curl-format.txt" -o /dev/null -s http://backend-ip:port/api/test(curl-format.txt 包含 time_namelookup、time_connect、time_starttransfer 等)
- 重点比对 time_starttransfer(TTFB)与 Nginx 的 $upstream_header_time 是否接近;若直连快、Nginx 慢,说明问题出在 proxy_pass 配置或复用机制
- 检查响应头是否有 Transfer-Encoding: chunked 或缺失 Content-Length,这类响应容易因 proxy_read_timeout 触发误断连
检查 upstream 连接复用是否生效
连接未复用会导致每次请求都重走 DNS + TCP 握手,放大延迟:
- 确认 upstream 块中启用了 keepalive 32;,且对应 location 中有 proxy_http_version 1.1; 和 proxy_set_header Connection "";
- 观察 Nginx error.log 是否频繁出现 upstream sent no valid HTTP/1.0 header 或 broken pipe,这是连接复用失败的典型信号
- 用 ss -tnp | grep :backend_port 查看当前到后端的 ESTAB 连接数,若远高于 keepalive 设置值,说明复用未生效,可能因后端不支持长连接或防火墙干扰

















