一、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端口
}
}
二、破案工具包:必备的排查姿势
工欲善其事必先利其器,我的排查三件套是:
- Nginx错误日志:就像汽车的故障码
- curl命令:比浏览器更透明的检测工具
- 网络检测工具: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; # 保持长连接
}
四、进阶排查:当基础方法失效时
如果上述方法都没解决问题,就需要上硬核手段了:
strace抓系统调用:
sudo strace -p $(pgrep nginx) -f -s 512检查系统限制:
ulimit -a # 查看打开文件数限制 sysctl net.core.somaxconn # 查看TCP连接队列内存监控:
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错误往往另有隐情。常见问题包括:
- 容器间网络不通
- 端口映射错误
- 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错误中学到的
- 监控先行:配置Zabbix或Prometheus监控Nginx的502错误率
- 渐进式变更:每次只改一个配置项并观察效果
- 文档习惯:所有线上变更必须记录,包括回滚步骤
- 容量预估:提前做好压力测试,知道系统的极限在哪
最后送大家一个万能检查清单:
- [ ] 后端服务是否存活?
- [ ] 端口是否正确?
- [ ] 防火墙是否放行?
- [ ] 资源是否充足?
- [ ] 配置语法是否正确?
记住,每个502错误背后都有一个有趣的故事。保持耐心,掌握方法,你也能成为Nginx神医。
评论