可通过Nginx access_log配合awk、sort、uniq等命令高效统计QPS和请求耗时分布:按秒截取$time_local统计QPS;用$request_time计算P50/P90/P95/P99;筛选$NF>1定位慢请求URI;需注意日志格式、列序、压缩处理及request_time的含义。

通过 Nginx 自带的 access_log,结合简单脚本和常用命令行工具(如 awk、sort、uniq),就能高效统计 QPS 和请求耗时分布,无需额外部署监控系统。
提取每秒请求数(QPS)
Nginx 日志默认时间戳只精确到秒(如 [10/Jan/2024:14:22:35),适合按秒聚合。关键是从日志中截取时间字段,再统计每秒出现次数:
- 假设日志格式为:log_format main '$time_local $status $body_bytes_sent $request_time';
- 用 awk 提取第一列(含日期和时间),再用 cut 截出“小时:分钟:秒”部分:
- awk '{print $1}' access.log | cut -d: -f2,3,4 | sort | uniq -c | sort -nr | head -20
- 输出形如 142 14:22:35,即该秒内 142 个请求;取 topN 即可识别瞬时峰值 QPS
统计请求耗时分布(P50/P90/P95/P99)
$request_time 是 Nginx 记录的后端处理耗时(单位:秒,精度为毫秒),需确保日志格式中已启用该变量:
- 检查 log_format 是否包含 $request_time,例如:log_format main '... $request_time';
- 提取所有耗时值并转为毫秒,便于分位计算:
- awk '{printf "%.0f\n", $NF * 1000}' access.log | sort -n | awk 'BEGIN{c=0} {a[++c]=$1} END{p50=int(c*0.5); p90=int(c*0.9); p95=int(c*0.95); p99=int(c*0.99); print "P50:" a[p50] "ms"; print "P90:" a[p90] "ms"; print "P95:" a[p95] "ms"; print "P99:" a[p99] "ms"}'
- 注意:$NF 表示最后一列,前提是 $request_time 在日志行末尾;否则需用 $n 显式指定列号(如 $12)
快速识别慢请求(>1s)及高频路径
定位性能瓶颈常需关联耗时与 URI,可一次性筛选并排序:
- 找出耗时超 1 秒的请求,并按 URL 分组统计次数:
- awk '$NF > 1 {print $7}' access.log | sort | uniq -c | sort -nr | head -10
- 其中 $7 假设是 $request_uri 字段(需根据实际日志列序调整),结果展示最常出现的慢请求路径
- 进一步加耗时信息:awk '$NF > 1 {print $NF " " $7}' access.log | sort -nr | head -10,看具体哪些请求最慢
自动化建议与注意事项
日常监控不建议手动跑命令,可封装为定时脚本或配合 logrotate 使用:
- 用 cron 每分钟执行一次 QPS 统计,写入临时文件,应用读取最新值做告警
- 注意日志轮转:若 access.log 被 gzip 压缩,需先用 zcat 处理,如 zcat access.log.1.gz | awk ...
- 高流量场景下,单行 awk 可能较慢,可先用 grep 过滤时间段(如近 5 分钟)再分析,提升效率
- request_time 不含网络传输时间,仅反映 Nginx 接收请求到发出响应的处理耗时;如需端到端延迟,应使用 $upstream_response_time










