Nginx 反向代理踩坑记录:超时、413 与真实 IP
Nginx 做反向代理是部署 Web 应用的标配,但默认配置里有三个坑几乎人人都会踩:长任务超时、上传文件报 413、后端拿不到用户真实 IP。这篇把这三个坑的现象、原因和解决方式整理成笔记。
坑一:长任务执行到 60 秒就报 504
现象:应用里有个数据导出功能,本地跑没问题,部署到 Nginx 后面就报 504 Gateway Timeout,且每次都是 60 秒左右准时超时。
原因:Nginx 反向代理的默认读超时是 60 秒(proxy_read_timeout),后端超过这个时间没返回数据,Nginx 就主动断开。
解决:按需调整三个超时参数:
更好的思路:把分钟级的重任务改成异步——接口立刻返回任务 ID,前端轮询进度。把长请求硬撑在 HTTP 同步链路里,就算调大了超时,用户那边的体验也是”转圈五分钟”,而且占着连接。
坑二:上传大文件报 413
现象:上传一张 20MB 的图片,直接 413 Request Entity Too Large,后端日志里连请求都没收到。
原因:Nginx 默认限制请求体大小为 1MB(client_max_body_size 的默认值),超过就直接拒绝,请求根本不会转发给后端。
解决:
注意两点:
这个指令放在
http块是全局生效,放在server或location里则只对对应范围生效,按需选层级如果后面还挂了 PHP,
php.ini里的upload_max_filesize和post_max_size也要一起调,取的是两者中更小的那个限制
坑三:后端拿到的客户端 IP 全是 127.0.0.1
现象:反代部署后,应用日志里记录的”用户 IP”清一色是 127.0.0.1,限流、风控、日志审计全部失效。
原因:Nginx 转发请求时,对后端来说 TCP 连接的来源就是 Nginx 本机。用户的真实 IP 在 TCP 层已经”丢失”,只能靠 HTTP 头传递。
解决:Nginx 转发时带上真实 IP 的头,后端应用读取这些头:
后端读取顺序:先取 X-Real-IP,取不到再取 X-Forwarded-For 的第一个地址。
一个安全提醒:X-Forwarded-For 是可以被伪造的请求头。如果前面还有 CDN 或多层代理,应该信任最靠近应用的那一层代理追加的 IP,而不是盲信请求头里任意位置的值,否则限流和风控都能被绕过。
三件事放在一起看
这三个坑的共同点是:单测和本地直连时永远不会发现,一挂到反向代理后面就暴露。所以服务器上线前的验证清单里,我固定会加三条:
跑一遍最长的那个业务接口,确认没有 504
按业务最大文件规格传一次文件,确认没有 413
打一条测试请求的日志,确认应用记录的是真实 IP
反代配置就是这样一个环节:每个参数都简单,但组合起来不实测就是会出问题。踩过一遍,就把验证固化成清单。
以上配置基于 Nginx 1.24 稳定版验证,指令细节以官方文档为准。
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: