一、502错误初印象:当浏览器对你say no

想象一下这个场景:你刚部署完网站,兴冲冲打开浏览器,结果迎面而来的是一个冷冰冰的"502 Bad Gateway"。就像外卖小哥告诉你"餐厅厨房炸了",但具体是油锅着火还是煤气泄漏,你得自己找原因。

502错误本质上就是Nginx作为中间人,无法从上游服务(比如PHP、Node.js等)获取有效响应。我遇到过最离谱的案例是,某电商大促时因为一个配置符号错误,导致每秒损失上万订单。下面这个最简单的Nginx配置就能复现问题:

# 技术栈:Nginx
server {
    listen 80;
    server_name example.com;
    
    location / {
        # 这里故意写错后端地址
        proxy_pass http://localhost:9999; # 实际后端运行在3000端口
    }
}

二、破案工具包:必备的排查姿势

工欲善其事必先利其器,我的排查三件套是:

  1. Nginx错误日志:就像汽车的故障码
  2. curl命令:比浏览器更透明的检测工具
  3. 网络检测工具:ping/telnet/nc三剑客

先看错误日志,位置通常在/var/log/nginx/error.log。建议这样配置日志级别:

# 技术栈:Nginx
events {}
http {
    log_format main '$remote_addr - $status "$request"';
    error_log /var/log/nginx/error.log warn; # 设置为debug级别可查看更多细节
}

用curl测试时,我习惯这样操作:

curl -v http://localhost/api -H "Host: example.com"
# -v 参数会显示详细请求过程
# -H 设置Host头模拟真实访问

三、经典翻车现场:五种常见配置错误

3.1 超时设置太短

当后端处理需要10秒,但Nginx默认只等60秒时:

# 技术栈:Nginx
location /upload {
    proxy_pass http://backend;
    proxy_read_timeout 60s; # 大文件上传需要调大
    proxy_connect_timeout 15s;
}

3.2 缓冲区不够用

接收大响应时内存不够:

# 技术栈:Nginx
location /report {
    proxy_buffers 16 32k; # 默认8个4k缓冲区
    proxy_buffer_size 64k;
}

3.3 头信息被吃掉

后端返回的重要头信息丢失:

# 技术栈:Nginx
location / {
    proxy_pass http://backend;
    proxy_set_header Host $host;
    proxy_pass_request_headers on; # 默认就是on
}

3.4 重定向循环

当Nginx和后端互相甩锅时:

# 技术栈:Nginx
location /admin {
    proxy_pass http://backend/admin/; # 注意结尾斜杠
    proxy_redirect http://backend/ /; # 重定向修正
}

3.5 连接数爆满

后端服务过载的情况:

# 技术栈:Nginx
upstream backend {
    server 127.0.0.1:3000 max_conns=100; # 限制单个worker连接数
    keepalive 32; # 保持长连接
}

四、进阶排查:当基础方法失效时

如果上述方法都没解决问题,就需要上硬核手段了:

  1. strace抓系统调用

    sudo strace -p $(pgrep nginx) -f -s 512
    
  2. 检查系统限制

    ulimit -a # 查看打开文件数限制
    sysctl net.core.somaxconn # 查看TCP连接队列
    
  3. 内存监控

    watch -n 1 "free -m && grep -i 'out of memory' /var/log/syslog"
    

五、防患于未然:最佳实践指南

根据多年填坑经验,推荐这些配置模板:

# 技术栈:Nginx
http {
    proxy_intercept_errors on;
    proxy_next_upstream error timeout;
    proxy_cache_path /tmp/cache levels=1:2 keys_zone=my_cache:10m;
    
    server {
        location / {
            proxy_pass http://backend;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_http_version 1.1;
            
            # 超时保险箱
            proxy_connect_timeout 5s;
            proxy_send_timeout 10s;
            proxy_read_timeout 30s;
            
            # 错误处理
            error_page 502 /custom_502.html;
            location = /custom_502.html {
                root /usr/share/nginx/html;
            }
        }
    }
}

六、特别篇:容器化环境下的坑

在Docker环境中,502错误往往另有隐情。常见问题包括:

  1. 容器间网络不通
  2. 端口映射错误
  3. DNS解析问题

典型docker-compose配置示例:

# 技术栈:Docker + Nginx
version: '3'
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    depends_on:
      - app
    networks:
      - mynet

  app:
    image: myapp:latest
    expose:
      - "3000"
    networks:
      - mynet

networks:
  mynet:
    driver: bridge

对应的Nginx配置需要特别注意主机名:

# 技术栈:Nginx
location / {
    proxy_pass http://app:3000; # 使用服务名而非localhost
}

七、终极武器:性能调优参数

对于高并发场景,这些内核参数能救命:

# 临时生效设置
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=8192

# 永久生效需要写入/etc/sysctl.conf

对应的Nginx调优:

# 技术栈:Nginx
events {
    worker_connections 4096;
    multi_accept on;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
}

八、经验总结:从502错误中学到的

  1. 监控先行:配置Zabbix或Prometheus监控Nginx的502错误率
  2. 渐进式变更:每次只改一个配置项并观察效果
  3. 文档习惯:所有线上变更必须记录,包括回滚步骤
  4. 容量预估:提前做好压力测试,知道系统的极限在哪

最后送大家一个万能检查清单:

  • [ ] 后端服务是否存活?
  • [ ] 端口是否正确?
  • [ ] 防火墙是否放行?
  • [ ] 资源是否充足?
  • [ ] 配置语法是否正确?

记住,每个502错误背后都有一个有趣的故事。保持耐心,掌握方法,你也能成为Nginx神医。