场景
某微服务部署使用 Nginx 作为反向代理和 TLS 终结器,前置集成的 API 网关中间件(如 Kong,基于 OpenResty/Nginx)处理认证、限流和请求路由。在流量高峰后的一个月内,运维团队观察到平均响应时间从 120ms 增长到 800ms,p99 延迟超过 2 秒。部分用户开始收到 504 Gateway Timeout 错误。网关的 CPU 利用率周期性地达到 95%,上游应用日志中连接重置增加。系统未完全宕机,但用户体验急剧下降。
症状
- 高延迟(p99 > 2s)和频繁超时
- Nginx/网关节点 CPU 饱和
- 5xx 错误增加,特别是 502/504
- 上游连接被丢弃
- 错误日志中出现 “worker_connections are not enough” 和 “upstream timed out”
诊断
从系统指标、Nginx 状态、日志开始,然后通过压力测试深入定位。
- 检查系统资源:使用
top、vmstat和mpstat查看 CPU、内存和 I/O。高sy时间表示内核/系统调用频繁,通常由上下文切换过多导致。 - 检查 Nginx 工作连接:
ngx_http_stub_status_module可暴露基本计数器。在 location 块中启用它并 curl:location /nginx_status { stub_status; allow 127.0.0.1; deny all; }然后curl http://127.0.0.1/nginx_status。关注 “Active connections” 和 “Waiting” 与 “Writing” 的对比。 - 检查 Nginx 错误日志:
tail -n 100 /var/log/nginx/error.log。常见消息: - “upstream timed out (110: Connection timed out)” — 检查 proxy_read_timeout。 - “no live upstreams” — 检查上游服务器的健康检查。 - “worker_connections are not enough” — 增加 worker_connections 或减少 keepalive 连接。 - 检查 API 网关中间件日志(例如 Kong 的 error.log)。对于 Kong,也可以查询
/status端点获取集群状态。 - 解析 Nginx 访问日志中的响应时间。如果使用
$request_time变量,可以直接看到慢请求。例如:tail -f /var/log/nginx/access.log | awk '{print $NF}'(时间在最后一个字段时)。 - 使用
wrk或ab对测试端点进行受控负载测试,以隔离瓶颈在 Nginx 还是网关中间件:wrk -t4 -c100 -d30s http://your-gateway/health与直接访问上游应用的响应进行对比。
命令与应急动作
以下是收集数据和开始修复的实用命令,并附有安全注意事项。
- 在重新加载前验证配置:
nginx -t -c /etc/nginx/nginx.conf(必须以 root 或适当权限运行)。 - 优雅重载 Nginx:
nginx -s reload(有权限时;systemd 下用systemctl reload nginx)。 - 如果看到 “worker_connections are not enough”,临时在 events 块中增加 worker_connections。这需要重载,只要文件描述符充足(
ulimit -n)就是安全的。 - 优化到上游的 keepalive:在 Nginx 的 upstream 块中确保
keepalive 32;,在 location 块中设置proxy_http_version 1.1;和proxy_set_header Connection "";,以复用上游连接,大幅减少内存和 CPU 占用。 - 针对上游超时,将
proxy_connect_timeout、proxy_send_timeout、proxy_read_timeout调整为合理值(例如 5s、10s、60s)。不要设置过高,否则会占用 worker 连接。 - 对于 API 网关中间件(假设 Kong),使用其 admin API 检查性能插件。如果启用了限流,查询计数器,确保限流没有导致限流。
- 使用
strace -p <nginx_pid> -f -e trace=network观察几秒钟,看系统调用是否阻塞(仅在可接受时使用,会引入开销)。 - 检查打开的文件描述符:
lsof -p $(pidof nginx) | wc -l,确认 worker 进程是否达到限制。
风险控制:任何改动应首先在单个节点上应用(如果前面有负载均衡器)。保留当前配置的备份:cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak。通过 upstream 块中的权重逐渐转移流量(金丝雀发布)。如果修改网关插件,通过 admin API 操作,并在预发环境测试。
回滚
如果调整导致更糟的行为或错误,立即回滚。
- 对于 Nginx 配置改动,将配置替换为 .bak 文件,运行
nginx -t然后nginx -s reload。这是优雅回滚,不会中断现有连接。 - 对于 API 网关插件改动,可以通过 admin API 禁用插件,或回退到之前的声明式配置(如果使用声明式模式)。
- 证书更改(例如 TLS 会话)必须有回滚计划。错误的配置会被
nginx -t捕获。
验证
应用更改后,验证问题是否解决。
- 监控关键指标:
nginx_status值(Active connections 应稳定)、访问日志中的响应时间($request_time)和错误率。 - 使用相同参数再次运行负载测试,比较 p99 和错误率。
- 如果有 Grafana 和 Prometheus,用仪表盘可视化变化。
- 使用
curl -v https://your-api/endpoint确保 TLS 握手顺畅且无额外延迟。
何时提交 OpsGlobal 工单
如果调整 worker_connections、keepalive 和超时后仍发现高 CPU 使用率,或者网关中间件本身成为瓶颈(例如 Kong 的数据库连接池、Lua JIT 或自定义插件),是时候引入专家了。OpsGlobal 可以使用 eBPF/perf 等跟踪工具进行深度分析,检查 Nginx 和网关内部,并实施高级性能策略,如动态上游管理、配置优化和内核调优。如果问题影响生产可用性,请立即提交工单以最大程度减少停机时间。
适用场景
适合正在处理 Performance、Nginx, API网关, 性能调优, SRE 相关问题的团队,用于快速建立排查路径和交付标准。
问题背景
深入探讨如何诊断并解决 Nginx 与 API 网关中间件场景下的性能问题。本指南涵盖基于场景的故障排查、命令行诊断、风险控制、回滚策略和验证方法,以及何时应使用 OpsGlobal 的专业 SRE 服务。
排查步骤
先确认影响范围和最近变更,再收集日志、配置、指标和链路数据,最后按风险从低到高执行修复。
命令示例
示例命令请替换为你的真实资源名,并使用环境变量保存账号、密码、token 等敏感信息。
风险说明
生产环境操作前需要确认备份、权限边界、变更窗口和回滚路径,避免扩大故障影响。
回滚方案
保留原配置和发布版本;如修复后指标异常,立即回退配置、镜像或数据库变更并复核日志。
交付清单
问题定位记录、关键命令、修复步骤、验证结果、后续优化建议。
遇到类似技术问题?
如果你的服务器、K8s、Docker、CI/CD、数据库或监控系统出现类似问题,可以提交日志和配置文件,我们帮你远程诊断。