nginx可通过$request_time记录完整响应时间(秒级,毫秒精度),配合$upstream_response_time定位瓶颈;支持map转毫秒或日志分析工具转换;配置后需重载生效并验证日志输出。

在 Nginx 中,可以通过自定义 log_format 指令,将每个请求的响应时间(即服务器处理该请求所花的时间)记录到 access log 中,便于后续性能分析和监控。
使用 $request_time 记录完整响应时间
$request_time 是 Nginx 内置变量,表示从接收到客户端第一个字节开始,到向客户端发送完最后一个字节为止的总耗时(单位:秒,精度为毫秒,如 0.003 表示 3 毫秒)。这是最常用、最贴近“用户感知延迟”的指标。
配置示例如下:
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
<p>access_log /var/log/nginx/access.log main;</p>注意:$request_time 在日志写入时才计算完成,因此它一定准确反映本次请求的真实耗时。
区分 upstream_response_time 获取后端耗时
如果 Nginx 作为反向代理(如转发给 FastAPI、Tomcat、PHP-FPM),可配合 $upstream_response_time 查看后端服务的响应时间。该变量记录 Nginx 与上游服务器交互的耗时(多个 upstream 会以逗号分隔,如 0.002, 0.004)。
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
- 若
$request_time明显大于$upstream_response_time,说明瓶颈可能在 Nginx 本身(如大文件传输、gzip 压缩、SSL 握手等) - 若两者接近,说明耗时主要由后端服务决定
格式化输出毫秒级时间(更易读)
默认 $request_time 是秒为单位的小数,若希望以整数毫秒形式记录(如 127 而非 0.127),可借助 Nginx 的 map 指令做转换:
map $request_time $request_time_ms {
~^(?P<msec>\d+\.\d{3})$ "${msec}000";
~^(?P<msec>\d+\.\d{2})$ "${msec}00";
~^(?P<msec>\d+\.\d{1})$ "${msec}0";
~^(?P<msec>\d+)$ "${msec}000";
default "0";
}
<p>log_format main '... $request_time_ms';</p></msec></msec></msec></msec>不过更推荐用日志分析工具(如 awk、Logstash、Grafana Loki)在读取时乘以 1000 转换,避免 map 增加运行时开销。
验证日志是否生效
修改配置后需重载 Nginx:
nginx -t && nginx -s reload
然后发起一次请求(如 curl http://localhost/),检查 access log 是否出现新增字段:
127.0.0.1 - - [10/Jul/2024:15:22:33 +0800] "GET / HTTP/1.1" 200 612 "-" "curl/7.81.0" 0.002 0.002
末尾两个数值即 $request_time 和 $upstream_response_time。










