预约咨询 提交工单

Nginx 作为 API 网关:性能故障排查深度实践

了解如何诊断和解决基于 Nginx 的 API 网关的性能瓶颈,包含实用命令、风险控制和回滚策略。

Nginx 作为 API 网关:性能故障排查深度实践
Performance 7min 9 浏览 2026-08-09
NginxAPI网关性能调优SRE故障排查

Nginx 作为 API 网关:性能故障排查深度实践

场景

在 OpsGlobal,我们经常看到客户将 Nginx 作为微服务前面的 API 网关运行。典型设置包括 Nginx 终止 TLS、将请求路由到上游服务,以及处理速率限制或缓存。最近,我们的一位客户报告说他们的 API 延迟从 50 毫秒飙升至 2 秒以上,并且在业务高峰时段出现间歇性 504 网关超时。

症状

  • 响应延迟增加(p95 延迟增加了三倍)
  • 当上游在默认超时时间内未能响应时,Nginx 返回 504 错误
  • Nginx worker 连接数达到 worker_connections 限制
  • 上游服务 CPU 使用率高但未饱和
  • 没有明显的代码变更或部署事件

诊断

我们首先检查基础知识:

  1. 检查 Nginx 错误日志 tail -f /var/log/nginx/error.log 查找 upstream timed outno live upstreams

  2. 检查访问日志中的慢请求 我们在日志格式中启用了 $request_time$upstream_response_time。配置和查看日志的命令。

  3. 验证 Nginx 配置nginx -tnginx -T 来转储完整配置。

  4. 测试到上游的连接和计时: 使用 curl -w 测量 DNS、连接、TLS、TTFB 和总时间。

  5. 检查连接池统计ss -s 查看套接字统计信息,以及 netstat -an | grep ESTABLISHED | wc -l

  6. 使用 wrkab 进行负载测试,在受控负载下重现问题。

我们发现 Nginx 配置中 proxy_connect_timeoutproxy_read_timeout 设置为默认值(60 秒),但真正的问题是没有正确配置上游 keepalive 连接。upstream 块中没有 keepalive 指令,导致每个请求都进行新的 TCP 连接和 TLS 握手。在高并发下,这增加了大量开销。

使用的命令

以下是我们在诊断和修复过程中使用的关键命令:

检查错误日志

tail -f /var/log/nginx/error.log

检查带有计时信息的访问日志

访问日志格式定义:

log_format timed '$remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent" '
                 '$request_time $upstream_response_time';

然后查看日志:

tail -f /var/log/nginx/access.log | awk '$10 > 2 {print}'

(假设第 10 个字段是 request_time)

验证配置

nginx -t
nginx -T

Curl 计时

curl -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://api.example.com/health

套接字统计

ss -s
ss -tn state established '( dport = :443 or sport = :443 )' | wc -l

使用 wrk 进行负载测试

wrk -t8 -c200 -d30s https://api.example.com/health

实施修复与风险控制

我们做了以下更改:

  1. 启用上游 keepalive
upstream backend {
    server api1:8080 weight=3;
    server api2:8080 weight=2;
    keepalive 32;
}
  1. 调整 Nginx HTTP 设置
http {
    upstream backend {
        server api1:8080;
        keepalive 32;
    }

    server {
        listen 443 ssl;

        location /api/ {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_connect_timeout 5s;
            proxy_read_timeout 10s;
            proxy_send_timeout 10s;
            proxy_buffering off; # 仅当需要时
        }
    }
}
  • proxy_http_version 1.1 是上游 keepalive 所必需的。
  • 空的 Connection 头。
  • 减少超时时间以防止长时间挂起。
  1. 调整 worker 进程/连接数: - 设置 worker_processes auto; 以匹配 CPU 核心数。 - 将 worker_connections 增加到 4096 或更高。 - 调整客户端连接的 keepalive_timeout

在应用之前,我们: - 备份了原始配置:cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak - 在与生产环境镜像的 staging 环境中进行了测试。 - 在 reload 之前使用 nginx -t 进行了验证。

我们使用了 nginx -s reload 进行优雅重载,它会创建新的 worker 并排空旧连接。

回滚策略

如果更改导致问题:

  • 恢复备份:cp /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf
  • 测试:nginx -t
  • 重载:nginx -s reload

如果问题很严重,我们可以使用符号链接快速切换到旧配置(如果保留了多个版本)。

验证与结果

重载后,我们监控了错误日志、访问日志和外部指标(例如 Datadog)。

  • tail -f /var/log/nginx/error.log 显示不再有超时错误。
  • wrk 基准测试显示吞吐量和延迟提高了 40%。
  • ss -s 套接字统计显示新建 TCP 连接减少,因为 keepalive 被重用。
  • 客户的 p95 延迟下降回约 80 毫秒。

何时提交 OpsGlobal 工单

这种级别的故障排查通常可以由公司内部的 DevOps 团队完成。然而,如果你遇到以下情况,就是时候请 OpsGlobal 介入了:

  • 你不熟悉 Nginx 内部机制,或者不习惯编辑生产配置。
  • 基本调优后问题仍然存在,可能需要调整内核参数(例如 tcp_tw_reusesomaxconn)或系统级调优。
  • 你需要水平扩展网关,需要负载均衡器设计或服务网格集成方面的专业知识。
  • 症状指向上游服务异常,需要帮助追踪或检测微服务。

OpsGlobal 提供 24/7 支持。我们可以接管事件响应、执行深入的性能审计,并实施具有适当回滚计划的生产变更。

适用场景

适合正在处理 Performance、Nginx, API网关, 性能调优, SRE 相关问题的团队,用于快速建立排查路径和交付标准。

问题背景

了解如何诊断和解决基于 Nginx 的 API 网关的性能瓶颈,包含实用命令、风险控制和回滚策略。

排查步骤

先确认影响范围和最近变更,再收集日志、配置、指标和链路数据,最后按风险从低到高执行修复。

命令示例

示例命令请替换为你的真实资源名,并使用环境变量保存账号、密码、token 等敏感信息。

风险说明

生产环境操作前需要确认备份、权限边界、变更窗口和回滚路径,避免扩大故障影响。

回滚方案

保留原配置和发布版本;如修复后指标异常,立即回退配置、镜像或数据库变更并复核日志。

交付清单

问题定位记录、关键命令、修复步骤、验证结果、后续优化建议。

!

遇到类似技术问题?

如果你的服务器、K8s、Docker、CI/CD、数据库或监控系统出现类似问题,可以提交日志和配置文件,我们帮你远程诊断。

工单 WhatsApp 联系 咨询