Nginx 反向代理:五个最常踩的配置坑
背景
Nginx 做反向代理,配置本身不长,但每次换项目几乎都会在同一批地方出问题:WebSocket 连不上、上传大文件 413、后端拿不到真实 IP、重定向跑到了内网地址。这几条都不是「配置写错了」,而是「默认值不合适」。下面按踩坑频率排一下。
一、WebSocket 连不上:忘了 Connection 头
最典型的现象是页面能打开,但实时推送一直「连接中」,控制台报 101 握手失败。proxy_pass 本身没问题,缺的是把 Upgrade 头透传过去:
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
注意 proxy_http_version 必须是 1.1,默认是 1.0,而 1.0 不支持 Upgrade。另外 proxy_read_timeout 默认 60 秒,长连接会被无声掐断,表现是「每分钟断一次」。
二、上传大文件 413
client_max_body_size 默认只有 1M,超过就直接 413,而且后端完全收不到请求,日志里看不出业务异常。要么在 http 块统一放大,要么只对上传接口放:
location /api/upload {
client_max_body_size 100m;
client_body_timeout 120s;
proxy_pass http://backend;
}
三、后端拿到的全是 172.x 内网 IP
经过代理后 remote_addr 变成 Nginx 自己的地址。要传真实 IP,得主动加上这几个头,同时让后端信任它们:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
后端侧(以 Django 为例)还要配置 USE_X_FORWARDED_HOST 和可信代理层数,否则框架出于安全考虑不会采信这些头。X-Forwarded-For 是逗号分隔的链,取第一个才是客户端 IP,取最后一个通常是上一级代理。
四、重定向跳到内网地址或 http
后端生成的重定向用 http://127.0.0.1:8080/...,原因是它不知道自己对外是 https。上面 Host 和 X-Forwarded-Proto 两个头就是解决这个的。如果还有 CDN 在前面,要把 CDN 的回源 IP 段加进 set_real_ip_from,否则拿到的还是 CDN 节点 IP。
五、proxy_pass 结尾那个斜杠
proxy_pass http://backend/ 和 proxy_pass http://backend 差一个字符,行为完全不同:带斜杠会把 location 匹配到的前缀替换掉,不带则原样拼接。
location /api/ {
proxy_pass http://backend/; # /api/user -> /user
# proxy_pass http://backend; # /api/user -> /api/user
}
这条引发的 bug 往往很隐蔽——接口有时 200 有时 404,取决于路由有没有同名路径。改配置时建议顺手在注释里写清意图。
小结
反向代理的坑几乎都源于「默认值是为通用场景准备的」。上线前把这五项对一遍,能省掉大部分「本地好好的、线上不行」的排查时间。
- 点赞
- 收藏
- 关注作者
评论(0)