返回首页

全栈性能排障方法论 — Nginx → 应用 → 数据库 → 服务器

📅 创建于 2026-05-08 🔄 更新于 2026-05-11 📝 639 字

全栈性能排障方法论

核心原则

分层排查,从外到内,先排查容易确认的层,再深入复杂的层:

  1. 确认是全局问题还是局部问题
  2. 确认是网络问题还是服务端问题
  3. 确认是哪个服务的瓶颈

每个阶段要有明确目标——「我要确认什么?输出是什么?根据输出怎么判断?」


第一阶段:确认问题范围

# 从多地 curl 看响应时间差异
for i in {1..5}; do
  curl -o /dev/null -s -w "Time: %{time_total}s, HTTP: %{http_code}\\n" \
    -H "Host: www.example.com" http://123.45.67.89/api/homepage
done

# 查看 Nginx access_log 状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# 统计 5xx 错误是否增多
grep "2024-03-15T14:" /var/log/nginx/access.log | awk '{if($9>=500) print $0}' | wc -l

第二阶段:Nginx 层排查

# 查看 worker 进程资源
ps -eo pid,ppid,comm,%cpu,%mem,rss | grep nginx

# 查看当前并发连接数
ss -tn | grep :8080 | wc -l

# 查看 error_log 中的 502/504/超时
tail -n 200 /var/log/nginx/error.log | grep -E "502|504|upstream|timeout|connect"

# 统计 upstream 响应时间(需在 access_log 配置 $upstream_response_time)
awk '{if($2>5) print $0}' /var/log/nginx/access.log | head -20

关键判断: 直接访问 upstream 端口快,通过 Nginx 慢 → 问题在 Nginx 层。反之在 upstream/数据库层。

Nginx 层常见配置问题参见 nginx-config-pitfalls(location 匹配、proxy_pass 路径处理、upstream keepalive 等)。


第三阶段:上游应用层排查

# 确认 upstream 端口监听
ss -tlnp | grep -E "8080|3000|5000|9000"

# 直接测试 upstream 响应
time curl -s http://127.0.0.1:8080/api/data > /dev/null

# 查看应用日志
tail -n 100 /var/log/app/application.log | grep -E "ERROR|WARN|Exception"
journalctl -u app-backend --since "10 minutes ago" | grep -E "ERROR|Exception|slow"

第四阶段:数据库层排查

# 查看当前运行 SQL
mysql -u root -p -e "SHOW FULL PROCESSLIST;"

# 查看慢查询
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

# EXPLAIN 分析
EXPLAIN SELECT ...;

# 查看锁等待(MySQL 5.7)
SELECT r.trx_id, r.trx_mysql_thread_id, r.trx_query,
       b.trx_id, b.trx_mysql_thread_id, b.trx_query
FROM information_schema.INNODB_LOCK_WAITS w
JOIN information_schema.INNODB_TRX b ON w.blocking_trx_id = b.trx_id
JOIN information_schema.INNODB_TRX r ON w.requesting_trx_id = r.trx_id;

# InnoDB 状态
SHOW ENGINE INNODB STATUS\G

详见 mysql-performance-config


第五阶段:服务器资源排查

# CPU
ps aux --sort=-%cpu | head -10
pidstat -p $(pgrep -f "mysqld" | head -1) 1 5

# 内存
free -h
dmesg | grep -iE "oom|mysql|killed" | tail -20

# OOMKilled 排查:参见 [[k8s-resource-limits-configuration]] 的 Burstable QoS 陷阱章节

# 磁盘 IO
iostat -x 1 3
iotop -o 2>/dev/null

# 网络
ss -s
netstat -an | awk '/:80\s/ {print $NF}' | sort | uniq -c | sort -rn

第六阶段:典型根因与快速定位

场景 特征 修复
Nginx upstream 超时 直连 upstream 快,走 Nginx 慢,504 增大 proxy_read_timeout
数据库连接池耗尽 PROCESSLIST 大量 Waiting for connection kill 慢查询 + 增大连接池
慢查询致 CPU 高 type=ALL, key=NULL, rows=数百万 加索引
InnoDB 缓冲池命中率低 命中率 < 95% 增大 innodb_buffer_pool_size
内存不足致 swap free -h 显示 swap 已用 增大物理内存或调小缓冲池

故障时间线复盘模板

记录每个关键时间点的操作,便于事后回顾:

14:02 - 收到投诉:首页加载慢
14:05 - 监控发现 502/504 错误率从 0.1% → 5%
14:08 - top 发现 CPU 100%,mysqld 占 90%
14:10 - SHOW PROCESSLIST 发现大量慢查询
14:12 - slow_query_log 发现定时任务大表 JOIN 无索引
14:20 - 联系开发确认 SQL
14:30 - 加索引,SQL 从 45s → 0.3s
14:35 - 监控恢复

预防性监控建议

指标 告警阈值 采集方式
Nginx 502/504 错误率 > 1% access_log 统计
upstream 响应时间 P99 > 3s access_log / Prometheus
MySQL 慢查询数/分钟 > 10/min slow_query_log
MySQL 连接数使用率 > 80% SHOW GLOBAL STATUS
InnoDB 缓冲池命中率 < 95% SHOW ENGINE INNODB STATUS
Swap 使用率 > 10% free -h
磁盘 IO util > 80% iostat

总结

网站变慢排查,核心是分层定位:

① 全局 vs 局部 → ② Nginx vs upstream → ③ 应用 vs 数据库 → ④ 数据库细分 → ⑤ 服务器资源

关键习惯:

  • 每个命令都要服务于某个假设的验证
  • 修复后必须有前后对比(5.2s → 0.3s)
  • 临时修复只是止血,系统性优化才是根治

关联页面

页面 关联点
ops-automation-scripts 运维自动化脚本 5 件套(健康巡检/日志告警/服务守护等,配合全栈排障使用)
server-performance-four-dimensions 五维排查框架与告警阈值
nginx-502-504-connection-reset-guide Nginx 502/504 深度排查
linux-disk-space-troubleshooting 磁盘空间排查
nginx-realtime-push-guide SSE/WebSocket 实时推送全链路排障
nginx-load-balancing-strategy-guide Nginx 负载均衡策略选择实战指南 — 加权轮询与 IP Hash 深度对比、混合策略最佳实践
nginx-log-analysis-monitoring-guide Nginx 日志分析与监控体系构建指南 — 自定义日志格式、性能分析技巧、GoAccess 可视化、
network-troubleshooting-order 网络排障七步法