能快速锁定“表面正常但实际卡顿”的数据库慢查询问题;关键在于筛选状态码为200且request_time≥1.0秒的动态接口请求,聚类分析高频路径与参数模式,并结合后端日志、数据库慢日志及explain analyze交叉验证,排除网络、系统资源等干扰因素。

直接看 Nginx 的 request_time 日志,能绕过应用层干扰,快速锁定“表面正常但实际卡顿”的数据库慢查询问题。关键不是等错误出现,而是抓那些返回 200 却耗时异常的请求。
盯住高耗时 + 200 状态的请求
在 Nginx access.log 中,request_time 表示整个 HTTP 请求从接收首字节到发送完响应的总时间(单位:秒,精度毫秒)。它包含网络传输、应用处理、数据库交互全过程。重点筛选:
- 状态码为 200:排除 5xx/4xx 等明显失败请求,聚焦“成功但慢”的真实瓶颈
-
request_time ≥ 1.0(或业务可接受阈值):比如设为 800ms,用 awk 或 grep 快速提取:
awk '$9==200 && $NF>=0.8 {print}' access.log - 排除静态资源路径:过滤掉 .js、.css、/images/ 等,专注动态接口如 /api/order/list、/user/profile
识别高频重复路径与参数模式
单次慢不说明问题,反复出现才暴露后端代码缺陷。对上一步结果进一步聚类:
- 按
$7(即 $request_uri)统计出现频次:awk '$9==200 && $NF>=0.8 {print $7}' access.log | sort | uniq -c | sort -nr | head -20 - 观察参数是否结构相似:比如
/search?q=xxx&page=1和/search?q=yyy&page=2都慢 → 暗示同一段 SQL 在不同参数下持续低效 - 若某路径占所有高耗时请求的 60% 以上,基本可判定对应后端服务存在慢 SQL 风险
关联后端日志与数据库慢日志
拿到可疑路径后,立刻转向后端服务和数据库验证:
- 查该接口对应的服务日志,确认其数据库操作耗时(如 Spring Boot 的
o.s.jdbc.core.JdbcTemplate日志,或 EF Core 的LogTo输出) - 同步检查数据库慢查询日志:
-
MySQL:确认
slow_query_log=ON、long_query_time=1,用mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log查总耗时 Top 10 -
PostgreSQL:检查
log_min_duration_statement = 1000,在日志中搜索duration:字段,并结合pg_stat_statements查平均耗时最高的 query
-
MySQL:确认
- 把 Nginx 中高频慢路径的参数(如
user_id=12345)代入对应 SQL,在数据库中执行EXPLAIN ANALYZE,确认是否走索引、是否回表、是否触发临时表或文件排序
避免误判:区分真慢 SQL 和环境干扰
request_time 高 ≠ 一定是 SQL 慢,需交叉验证排除其他因素:
- 如果多个不同路径都出现高 request_time,且集中在同一时间段,优先查系统级指标:CPU 是否打满、内存是否 OOM、磁盘 IO wait 是否飙升
- 对比
upstream_response_time(若有反向代理):若它远小于 request_time,说明卡点在 Nginx 到 upstream 之间(如网络抖动、连接池打满);若两者接近,问题大概率在 upstream 应用内部 - 查应用日志中是否有大量
Connection refused、timeout或线程阻塞堆栈,排除连接池耗尽或下游依赖(如 Redis、第三方 API)拖慢整体响应










