问题背景与现象描述
Nginx 502 Bad Gateway 是运维日常工作中遇到频率最高的错误之一。与 500 内部服务器错误不同,502 明确告诉我们:Nginx 已经成功接收到客户端请求,并且尝试与后端服务通信,但后端服务返回了一个无效的响应,或者根本连不上。
从 HTTP 协议层面来看,502 表示网关或代理从上游服务收到了无效响应。这意味着问题不在 Nginx 本身,而在于 Nginx 与后端之间的通信链路。常见的触发场景包括:后端 PHP-FPM 进程全部挂掉、后端 Tomcat / Node.js / Python 服务崩溃、数据库连接超时导致应用拒绝响应、Nginx 与后端之间的网络不通、或者后端服务在规定时间内没有响应完整 Headers。
当你看到浏览器返回 "502 Bad Gateway" 或 "502 Proxy Error" 时,第一反应不应该是慌,而是按照固定套路逐层排查:先看 Nginx 错误日志定位是谁在报错,再看后端服务状态和资源使用情况,然后检查网络连通性,最后分析配置和超时设置。下面的章节会把这个套路拆成可操作的具体步骤。
常见根因分析
在动手排查之前,先把 502 的常见原因梳理清楚,建立一个排查清单。根因大致可以分为以下几类:
第一类是后端服务不可用。这是 502 最常见的原因。后端服务进程崩溃、进程被 OOM Killer 杀掉、端口未监听、防火墙拦截、或者服务启动但无法正常响应请求,都会导致 Nginx 拿到无效响应从而返回 502。PHP-FPM 是最典型的例子,当 PHP-FPM 的 pm.max_children 达到上限、新请求排队超时、或者 PHP 进程因段错误崩溃时,Nginx 就会报 502。
第二类是资源耗尽。后端服务器或容器内存不足、CPU 打满、磁盘写满、文件描述符用光、或者进程数达到系统限制,都会导致后端服务无法正常处理请求。这种情况下的 502 通常是服务在资源紧张时主动拒绝连接或超时产生的。
第三类是配置不当。 Nginx 与后端之间的超时设置过短(proxy_connect_timeout、proxy_send_timeout、proxy_read_timeout),后端健康检查频率不够,或者负载均衡策略配置错误,都可能在正常运行时触发 502。尤其是超时设置偏短时,如果后端处理时间稍长,Nginx 就会主动关闭连接。
第四类是权限和文件句柄问题。后端服务运行用户与 Nginx 运行用户不一致、Unix Socket 权限不对、或者后端服务打开了过多连接导致文件描述符耗尽,都会造成 502。这类问题在切换 PHP-FPM 运行用户、修改 Socket 路径后容易出现。
第五类是网络层面问题。Nginx 与后端不在同一个网络区域、VPC 安全组规则变更、Docker 网络模式配置错误、或者 Docker Compose / Kubernetes 服务发现故障,都会导致 Nginx 无法连接到后端。这类问题通常伴随批量 502,而不是偶发单个。
排查路径与核心命令
遇到 502 不要慌,按下面的顺序逐层排查。
第一步:查看 Nginx 错误日志
Nginx 的错误日志是排查 502 的第一入口。大多数 Linux 发行版中,Nginx 错误日志默认路径为/var/log/nginx/error.log。执行以下命令查看最新错误:
tail -n 100 /var/log/nginx/error.log
或者实时跟踪日志输出:
tail -f /var/log/nginx/error.log
错误日志中通常会包含具体信息,例如:
2026/05/26 1015 [error] 12345#12345: *67890 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.100, server: example.com, request: "GET /api HTTP/1.1", upstream: "http://127.0.0.1:8080/api", host: "example.com"
这条日志告诉了我们几个关键信息:连接被拒绝(Connection refused),说明后端 127.0.0.1:8080 没有在监听;请求的是/api路径;上游服务器是http://127.0.0.1:8080。根据这个线索,直接去检查 8080 端口的服务状态即可。
如果日志显示的是 upstream prematurely closed connection,说明后端在 Nginx 发送请求过程中主动关闭了连接,常见原因包括后端进程崩溃或超时。如果日志是 no live getway while connecting,说明所有后端都不可用,Nginx 无法建立任何上游连接。
查看 Nginx 错误日志时,注意区分[error]和[warn]级别。warn 级别的日志可能只是性能警告,不一定导致 502,但 error 级别基本都伴随故障。
第二步:检查 Nginx 访问日志中的状态码分布
查看访问日志中 502 出现的频率和来源:
# 统计 502 出现的次数 grep'" 502 '/var/log/nginx/access.log | wc -l # 查看最近 502 请求的来源 IP 和请求路径 grep'" 502 '/var/log/nginx/access.log | tail -n 50 | awk'{print $1, $7, $12}' # 按 URL 统计 502 次数,找出高频中招的接口 grep'" 502 '/var/log/nginx/access.log | awk -F'"''{print $2}'| awk'{print $2}'| sort | uniq -c | sort -rn | head -20
如果 502 集中在特定接口或特定 IP,可以优先排查这些热点的后端服务。如果 502 分布均匀但数量突然增加,可能是后端整体负载上升或依赖服务(数据库、Redis)出现问题。
第三步:确认 Nginx 与后端的网络连通性
如果日志显示连接被拒绝,先验证网络层面是否通畅。使用 curl 在 Nginx 所在服务器直接访问后端:
# 测试后端端口是否可达
curl -v http://127.0.0.1:8080/api 2>&1
# 测试后端服务响应时间
curl -w"
时间: %{time_total}s
"http://127.0.0.1:8080/api
# 检查端口监听状态
ss -tlnp | grep :8080
netstat -tlnp | grep :8080
如果端口未监听,说明后端服务没有启动或启动失败了。如果端口监听中但 curl 无响应,可能是后端服务 hang 住了,或者防火墙拦截。
第四步:检查后端服务状态
根据后端类型(PHP-FPM、Node.js、Java、Python)分别检查:
PHP-FPM 场景:
# 查看 PHP-FPM 进程状态 ps aux | grep php-fpm | grep -v grep # 查看 PHP-FPM 连接池状态(需要启用 status_path) curl http://127.0.0.1:9000/status # 检查 PHP-FPM 错误日志 tail -n 50 /var/log/php-fpm/www-error.log # 查看 PHP-FPM 配置中的进程管理方式 grep -E"^(pm|pm.|pm.max)"/etc/php-fpm.d/www.conf
Java (Tomcat/Jetty) 场景:
# 查看 Java 进程是否存在,查看启动命令和内存配置 ps aux | grep java | grep -v grep # 检查 Tomcat 错误日志 tail -n 100 /var/log/tomcat/catalina.out # 查看 Tomcat 管理接口(如果有) curl -s http://127.0.0.1:8080/manager/status
Node.js / Python 场景:
# 查看进程是否存在 ps aux | grep -E'node|python'| grep -v grep # 查看进程启动时间和运行状态 ps -p $(pgrep -f"node server.js") -o pid,etime,cmd # 查看应用自定义日志 tail -f /var/log/myapp/application.log
第五步:检查服务器资源使用情况
502 经常是资源耗尽的表现。在后端服务器上执行:
# 查看 CPU 使用率 top -b -n 1 | head -20 # 查看内存使用情况 free -h # 查看磁盘空间 df -h # 查看进程数 ps aux | wc -l # 查看打开的文件描述符数量 lsof 2>/dev/null | wc -l # 查看最大文件描述符限制 cat /proc/sys/fs/file-max ulimit-n
如果发现内存不足(free + buffers/cache 接近 0),或者 OOM Killer 活跃(dmesg | grep -i oom 有输出),基本可以确认是资源问题导致的 502。OOM 问题会在后面的"内存不足"场景中详细说明。
第六步:检查 Nginx 超时配置
Nginx 默认的超时时间偏短,如果后端处理时间稍长就容易触发 502。在 Nginx 配置文件中检查以下参数:
proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s;
这三个超时含义不同:proxy_connect_timeout 是与后端建立连接的超时,proxy_send_timeout 是发送请求到后端的超时,proxy_read_timeout 是等待后端响应数据的超时。如果后端处理时间可能超过 60 秒,需要将这些值调大。
同时检查后端服务的超时配置。例如 Java Spring Boot 应用中 server.tomcat.connection-timeout,PHP 中的 max_execution_time,都是影响后端响应时长的配置。
常见场景与修复方案
场景一:PHP-FPM 进程全部挂掉
这是最经典的 502 场景。PHP-FPM 是多进程架构,如果所有子进程都因为某种原因退出,Nginx 就会报 502。
现象:访问任何 PHP 页面都返回 502,错误日志显示 connect() failed 或 no live workers。
排查步骤:
# 1. 检查 PHP-FPM 是否在运行 systemctl status php-fpm ps aux | grep php-fpm | grep -v grep # 2. 检查 PHP-FPM 错误日志 cat /var/log/php-fpm/error.log cat /var/log/php-fpm/www-error.log # 3. 如果进程不存在,尝试启动 systemctl start php-fpm # 4. 启动失败时查看详细错误 systemctl status php-fpm -l journalctl -u php-fpm -n 50
常见原因和修复:
原因一:PHP-FPM 内存泄漏导致进程崩溃。PHP-FPM 进程长期运行后可能发生内存泄漏,当物理内存耗尽时被系统 OOM Killer 杀掉。解决方法是在 php-fpm.conf 中配置 pm.max_requests(每个子进程处理多少请求后重启):
pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500
设置pm.max_requests = 500可以让 PHP-FPM 子进程处理 500 个请求后自动重启,防止内存泄漏累积。重启后观察是否还出现 502。
原因二:PHP 配置了不存在的 socket 文件或端口。检查 php-fpm.conf 中 listen 的值:
listen = /var/run/php-fpm/php-fpm.sock
然后检查 Nginx 配置中的 fastcgi_pass:
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
两者必须一致。如果 Nginx 配置的是fastcgi_pass 127.0.0.1:9000;而 PHP-FPM 监听的是 socket 文件,就会报 502。
原因三:Socket 文件权限问题。PHP-FPM 默认以 apache 或 nobody 用户运行,如果 Socket 文件权限不对,Nginx(通常以 nginx 用户运行)无法连接。修复方法:
listen.owner = nginx listen.group = nginx listen.mode = 0660
修改后重启 PHP-FPM:
systemctl restart php-fpm
场景二:后端 Java / Python / Node.js 服务崩溃
现象:访问后端 API 返回 502,但 PHP 页面正常。或者某个特定微服务返回 502,其他服务正常。
排查步骤:
# 1. 查看 Nginx 错误日志中的 upstream 信息 grep -A2'upstream'/var/log/nginx/error.log | tail -n 50 # 2. 在 Nginx 服务器上直接 curl 后端端口 curl -v http://backend:8080/health 2>&1 # 3. 检查后端服务进程 ps aux | grep java | grep -v grep ps aux | grep node | grep -v grep # 4. 查看后端服务日志 journalctl -u myapp --since"10 minutes ago" tail -n 200 /var/log/myapp/error.log
常见原因和修复:
原因一:后端进程崩溃退出。Java 应用如果遇到段错误、OOM 或未捕获异常会自动退出。检查方法:
# 查看系统日志中的 OOM 记录 dmesg -T | grep -i"out of memory" dmesg -T | grep -i"killed process" # 查看应用退出码 systemctl status myapp journalctl -u myapp -n 100 | grep -E"Exit|error|fail"
如果是 OOM 导致,需要增加 JVM 堆内存或调整容器资源限制:
# 查看当前 JVM 堆内存配置 ps aux | grep java | grep Xmx # 启动脚本中增加堆内存 exportJAVA_OPTS="-Xms512m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"
原因二:数据库连接超时导致后端拒绝请求。后端服务在启动时连接数据库失败,或者运行中数据库连接池耗尽,会导致后端对所有请求返回错误。Nginx 收到这个错误后返回 502。检查方法:
# 测试数据库连接 mysql -h db-server -u appuser -p -e"SELECT 1" # 查看后端应用数据库连接池配置(以 Spring Boot 为例) grep -E"spring.datasource|spring.jpa|connection-pool"/app/config/application.yml
后端 Java 应用的数据库连接超时配置(Spring Boot 示例):
spring: datasource: hikari: maximum-pool-size:20 minimum-idle:5 connection-timeout:30000 idle-timeout:600000 max-lifetime:1800000
如果数据库响应慢导致连接池耗尽,需要同时优化数据库查询性能和网络延迟。
场景三:内存不足导致后端进程被 OOM Killer 杀掉
现象:502 批量出现,持续一段时间后自动恢复。一段时间后再次出现。服务器负载和内存使用率很高。
排查步骤:
# 1. 检查系统内存
free -m
# 2. 查看哪些进程占用内存最多
ps aux --sort=-%mem | head -15
# 3. 查看 dmesg 中的 OOM Killer 日志
dmesg -T | grep -i"out of memory"
dmesg -T | grep -i"killed process"
# 4. 查看当前 OOM Killer 分数(分数越高越容易被杀)
forpidin$(ps aux | awk'{print $2}'| grep -v PID);do
echo"PID$pid:$(cat /proc/$pid/oom_score 2>/dev/null)-$(ps -p $pid -o comm= 2>/dev/null)"
done| sort -t: -k3 -rn | head -10
修复方案:
短期:释放内存或重启服务:
# 强制释放 pagecache sync &&echo3 > /proc/sys/vm/drop_caches # 重启占用内存大的服务 systemctl restart myapp
长期:增加物理内存、优化内存使用、配置 Swap:
# 检查 Swap 配置 swapon -s free -h # 如果没有 Swap,创建交换文件(以 4G 为例) fallocate -l 4G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile # 添加到 fstab 永久生效 echo'/swapfile none swap sw 0 0'>> /etc/fstab
同时调整 OOM Killer 偏好,降低重要服务被杀的概率:
# 查看进程的 OOM 分数 cat /proc/$(pgrep -f mysqld)/oom_score_adj # 设置 MySQL 被杀优先级降低(分数越低越不容易被 OOM Killer 杀) echo-10 > /proc/$(pgrep -f mysqld)/oom_score_adj
场景四:后端服务响应超时
现象:502 不是一开始就出现,而是在请求处理一段时间后出现。错误日志显示 upstream timed out 或 upstream prematurely closed connection。
排查步骤:
# 1. 在 Nginx 服务器手动测试后端响应时间 time curl -v http://backend:8080/api/heavy 2>&1 # 2. 查看 Nginx 超时配置 grep -E"timeout"/etc/nginx/conf.d/*.conf # 3. 查看后端服务慢查询日志(Java Spring Boot) grep -E"slowquery|slow query"/var/log/myapp/application.log # 4. 检查后端数据库查询性能 mysql -h db -u app -p -e"SHOW FULL PROCESSLIST;"
修复方案:
首先检查并调整 Nginx 超时配置:
server {
listen 80;
server_name example.com;
# 超时配置,根据业务实际处理时间调整
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
# 缓冲配置,减小高负载时的超时风险
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
location / {
proxy_pass http://backend;
}
}
然后检查后端服务的处理时间。如果后端需要执行数据库查询、文件 IO 或调用外部 API,需要逐一排查每个环节的耗时。对于 Java Spring Boot 应用,可以在 Controller 层添加耗时日志:
@RestController
publicclassApiController{
privatestaticfinalLogger logger = LoggerFactory.getLogger(ApiController.class);
@GetMapping("/api/heavy")
publicResponseEntityheavyEndpoint(){
longstart = System.currentTimeMillis();
logger.info("开始处理请求");
try{
String result = someHeavyOperation();
logger.info("请求处理完成,耗时: {}ms", System.currentTimeMillis() - start);
returnResponseEntity.ok(result);
}catch(Exception e) {
logger.error("请求处理异常,耗时: {}ms, 错误: {}", System.currentTimeMillis() - start, e.getMessage());
returnResponseEntity.status(500).body("处理失败");
}
}
}
场景五:Nginx 与后端的 Unix Socket 权限问题
现象:PHP-FPM 在运行,但某些请求返回 502。错误日志显示 Permission denied while connecting to upstream。
排查步骤:
# 1. 检查 Socket 文件权限
ls -la /var/run/php-fpm/
# 2. 检查 PHP-FPM 运行用户
ps aux | grep"php-fpm: master"| awk'{print $1}'
# 3. 检查 Nginx 运行用户
ps aux | grep"nginx: master"| awk'{print $1}'
# 4. 查看 Nginx 错误日志
tail -n 20 /var/log/nginx/error.log | grep -i permission
修复方案:
确保 PHP-FPM Socket 对 Nginx 有读写权限:
; php-fpm.conf 或 www.conf listen = /var/run/php-fpm/php-fpm.sock listen.owner = nginx listen.group = nginx listen.mode = 0660
修改后重启 PHP-FPM:
systemctl restart php-fpm # 验证 Socket 权限 ls -la /var/run/php-fpm/php-fpm.sock
如果是 SELinux 或 AppArmor 拦截了 Socket 连接,需要调整安全策略:
# 检查 SELinux 状态 getenforce # 临时关闭 SELinux(测试用) setenforce 0 # 永久关闭 SELinux(生产环境慎用) sed -i's/SELINUX=enforcing/SELINUX=disabled/'/etc/selinux/config
场景六:Docker 容器网络问题导致的 502
现象:在 Docker Compose 或 Kubernetes 环境中,部分容器间通信返回 502,但容器进程在运行。
排查步骤:
Docker Compose 环境:
# 查看容器运行状态 docker-compose ps # 查看容器日志 docker-compose logs -f backend # 进入 Nginx 容器测试网络连通性 docker-composeexecnginx sh -c"curl -v http://backend:8080/health" # 检查 Docker 网络 docker network ls docker network inspect
Kubernetes 环境:
# 查看 Pod 状态 kubectl get pods -n# 查看 Pod 日志 kubectl logs -n # 查看 Service 端点是否正常 kubectl get endpoints -n # 进入 Nginx Pod 测试连通性 kubectlexec-it -n nginx-pod -- sh -c"curl -v http://backend-service:8080/health" # 查看 Pod 网络策略 kubectl describe pod -n | grep -E"Events|Conditions"
常见问题和修复:
原因一:容器启动顺序问题。后端容器未就绪时 Nginx 已经启动,导致初始请求 502。解决方法是在 Nginx 中配置健康检查:
upstream backend {
server backend1:8080;
server backend2:8080;
keepalive 32;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 健康检查配置
proxy_connect_timeout 5s;
proxy_next_upstream error timeout http_502;
}
}
原因二:Docker 网络 driver 问题。某些情况下 overlay 网络或 bridge 网络配置不当会导致包丢失。检查容器 IP 是否能互通:
# 获取容器 IP
docker inspect -f'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'backend
# 从 Nginx 容器 ping 后端容器
docker-composeexecnginx ping -c 3 backend
场景七:高并发场景下的连接数耗尽
现象:502 在业务高峰期出现,低峰期正常。错误日志显示 connect() failed (99: Cannot assign address) 或 too many open files。
排查步骤:
# 1. 检查 Nginx 连接数 ss -s # 2. 查看后端服务的最大连接数 ss -ant | grep :8080 | wc -l # 3. 检查系统文件描述符限制 ulimit-n # 4. 查看后端服务连接数配置 ps aux | grep java | grep Xmx
修复方案:
调整系统文件描述符限制:
# 临时生效 ulimit-n 65535 # 永久生效(编辑 /etc/security/limits.conf) cat >> /etc/security/limits.conf << 'EOF' * soft nofile 65535 * hard nofile 65535 nginx soft nofile 65535 nginx hard nofile 65535 EOF # 重启 Nginx 使限制生效 systemctl restart nginx
调整 Nginx worker 连接数:
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
调整后端服务连接池大小。以 Java Spring Boot 为例:
server: tomcat: max-threads:800 max-connections:16384 accept-count:200
预防措施
502 问题排查清楚后,更重要的是建立预防机制,避免同类问题反复发生。
建立后端健康检查机制
在 Nginx 中配置被动健康检查,当后端连续失败一定次数后自动摘除:
upstream backend {
server backend1:8080 max_fails=3 fail_timeout=30s;
server backend2:8080 max_fails=3 fail_timeout=30s;
keepalive 32;
}
同时在负载均衡层做主动探测:
# 编写健康检查脚本
cat > /usr/local/bin/health-check.sh << 'EOF'
#!/bin/bash
BACKEND_URL="http://127.0.0.1:8080/health"
MAX_RESPONSE_TIME=3
response=$(curl -s -o /dev/null -w "%{http_code}" --max-time $MAX_RESPONSE_TIME$BACKEND_URL)
if [ "$response" != "200" ]; then
echo"$(date): Health check failed, response: $response" >> /var/log/health-check.log
exit1
fi
exit0
EOF
chmod +x /usr/local/bin/health-check.sh
# 添加到 crontab 每分钟执行
echo"* * * * * root /usr/local/bin/health-check.sh">> /etc/crontab
配置完整的监控告警
使用 Prometheus + Grafana 监控 Nginx 和后端服务状态。Nginx 需要启用 stub_status 模块:
server {
listen 8888;
server_name localhost;
stub_status on;
allow 127.0.0.1;
deny all;
}
Prometheus 抓取配置:
scrape_configs: -job_name:'nginx' static_configs: -targets:['localhost:8888']
设置关键告警规则:
groups:
-name:nginx_502_alert
rules:
-alert:High502Rate
expr:rate(nginx_http_requests_total{status="502"}[5m])>0.1
for:2m
labels:
severity:critical
annotations:
summary:"Nginx 502 错误率过高"
description:"502 错误率超过 10%,当前值:{{ $value }}"
完善日志记录和链路追踪
确保 Nginx 和后端服务都记录足够的日志信息,便于事后复盘:
Nginx 配置增强日志格式:
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'upstream_addr: $upstream_addr '
'upstream_status: $upstream_status '
'request_time: $request_time '
'upstream_response_time: $upstream_response_time';
access_log /var/log/nginx/access.log main;
后端 Java 应用添加请求 ID 串联日志:
@RestController
publicclassApiController{
privatestaticfinalLogger logger = LoggerFactory.getLogger(ApiController.class);
@GetMapping("/api/{id}")
publicResponseEntitygetApi(@PathVariable String id,
@RequestHeader(value ="X-Request-ID", required =false)String requestId){
String traceId = requestId !=null? requestId : UUID.randomUUID().toString();
MDC.put("traceId", traceId);
logger.info("收到请求, traceId={}, id={}", traceId, id);
try{
String result = apiService.getById(id);
returnResponseEntity.ok(result);
}finally{
MDC.remove("traceId");
}
}
}
定期演练和容量规划
建立 502 故障的应急演练机制,每季度进行一次演练:
# 演练脚本:模拟后端服务不可用 cat > /usr/local/bin/chaos-inject.sh << 'EOF' #!/bin/bash # 模拟后端服务崩溃(请在测试环境执行) TARGET_PID=$(pgrep -f "java.*myapp") if [ -n "$TARGET_PID" ]; then echo"正在终止进程: $TARGET_PID" kill -STOP $TARGET_PID echo"进程已暂停,Nginx 将返回 502,观察监控和告警" sleep 30 kill -CONT $TARGET_PID echo"进程已恢复" else echo"未找到目标进程" fi EOF
容量规划检查清单:
# 检查当前峰值 QPS
awk'{print $10}'/var/log/nginx/access.log | sort -rn | head -1
# 检查平均响应时间
awk'{sum+=$10; count++} END {print "平均响应时间: " sum/count "ms"}'/var/log/nginx/access.log
# 估算当前容量是否满足峰值需求
echo"当前 worker_connections:$(grep worker_connections /etc/nginx/nginx.conf)"
echo"当前 PHP-FPM max_children:$(grep 'pm.max_children' /etc/php-fpm.d/www.conf)"
验证修复结果
修复完成后,必须验证 502 不再出现,并且业务功能正常。
功能验证
# 使用 curl 遍历主要接口
forpathin"/""/api/users""/api/products""/health";do
status=$(curl -s -o /dev/null -w"%{http_code}"http://127.0.0.1$path)
if["$status"="200"] || ["$status"="301"] || ["$status"="302"];then
echo"[PASS]$path->$status"
else
echo"[FAIL]$path->$status"
fi
done
# 模拟并发请求
foriin{1..100};do
curl -s -o /dev/null -w"%{http_code}
"http://127.0.0.1/api/users &
done
wait
# 检查是否还有 502
grep'" 502 '/var/log/nginx/access.log | wc -l
监控指标验证
登录 Grafana 检查以下指标是否恢复正常:
Nginx 502 错误率:应该接近 0
后端服务响应时间:应该在正常范围内
PHP-FPM / 后端进程数:应该在正常范围内
服务器 CPU 和内存使用率:应该在正常范围内
数据库连接池使用率:不应该接近上限
日志验证
# 检查最近 1 小时内是否还有新的 502 grep"$(date -d '1 hour ago' '+%Y/%m/%d %H')"/var/log/nginx/error.log | grep -c error # 检查后端服务是否稳定运行 systemctl status myapp | grep"Active:" journalctl -u myapp --since"1 hour ago"| grep -E"ERROR|WARN"| wc -l
总结
Nginx 502 Bad Gateway 的排查有清晰的套路:先看 Nginx 错误日志定位是谁在报错,再检查后端服务是否存活和资源是否充足,然后排查网络连通性和配置超时问题。
常见根因可以归纳为五类:后端服务不可用、资源耗尽、配置不当、权限问题、网络故障。每类问题都有对应的排查命令和修复方案。
建立预防机制比被动排查更重要:配置健康检查、实现监控告警、完善日志记录、定期演练。这些措施可以在 502 发生的第一时间发现问题,而不是等到用户投诉才知道。
最后提醒一句:任何对 Nginx 配置、后端服务、数据库连接池的修改,都应该先在测试环境验证,再在生产环境灰度执行。修改前务必备份原配置文件,修改后立即验证功能正常。生产环境的每一次操作都要记录在案,便于事后复盘和回滚。
-
网关
+关注
关注
9文章
7074浏览量
56705 -
命令
+关注
关注
5文章
766浏览量
24121 -
nginx
+关注
关注
0文章
202浏览量
13248
原文标题:遇见 Nginx 502 报错?手把手快速排查解决
文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
nginx重启命令linux步骤是什么?
nginx重启命令linux步骤是什么?
nginx错误页面配置
分享nginx 502的解决方法
云原生环境里Nginx的故障排查思路
Nginx 502报错的常见根因和排查步骤
评论