Nginx 报 502 别急着重启:先分清是上游挂了还是连接池满了
Nginx 报 502 别急着重启:先分清是上游挂了还是连接池满了
标题:Nginx 报 502 别急着重启:先分清是上游挂了还是连接池满了
网站突然返回 502 Bad Gateway,很多人的第一反应是重启 Nginx。重启大多时候没用——502 的意思是 Nginx 本身活得好好的,是它去找上游服务时出了问题。重启 Nginx 只是把同一个请求重新发一遍,问题根源还在上游。不如花两分钟先分清:是上游进程挂了,还是上游活着但接不住请求。
第一步,看 Nginx 的错误日志。默认位置在 /var/log/nginx/error.log,搜最近的 502 时间点附近的记录。如果看到 connect() failed (111: Connection refused) while connecting to upstream,意思是上游根本没在监听那个端口:进程挂了、端口配错了、或者服务还没启动。这时该去看上游进程本身,用 ss -tlnp 确认端口有没有人在听,再用 systemctl status 看服务状态。重启 Nginx 对此毫无帮助,要重启的是上游。
如果日志写的是 upstream timed out (110: Connection timed out) while connecting to upstream,上游端口是通的,但请求发过去半天没回。常见原因有三个:一是上游应用卡住了,比如数据库连接池耗尽、某个慢查询堵住了所有工作线程;二是上游机器负载过高,CPU 跑满导致响应不过来;三是网络层面有问题,比如防火墙把回包丢了。这时用 curl 直接访问上游地址绕过 Nginx 测一次,如果直连也慢,问题就在应用层;如果直连很快,问题可能在 Nginx 与上游之间的网络或代理配置。
还有一种容易被忽略的情况:no live upstreams while connecting to upstream。这表示 Nginx 配置的上游组里所有节点都被标记为不可用。Nginx 的健康检查机制会在连续失败几次后把节点摘掉,如果你的上游只有一个节点,摘掉就等于全断。看到这条日志,别急着改配置,先确认上游是否真的恢复了——有时候上游只是短暂抖动了一下,Nginx 的失败计数却已经把它拉黑,max_fails 和 fail_timeout 配得太激进时尤其常见。
连接池满了是另一种典型 502。应用本身没挂,但并发一上来就顶不住:比如 Python 的 Gunicorn 只起了 4 个 worker,每个请求要跑 2 秒,理论上每秒只能处理 2 个请求,第 5 个并发请求进来,Nginx 等不到响应就超时。日志里同样是 upstream timed out,但直连上游测着也不慢——因为单请求确实不慢,慢的是排队。解决办法是增加 worker 数量、缩短单个请求的耗时,或者在 Nginx 层调大 proxy_read_timeout 给上游多一点时间。调超时只是缓兵之计,真正的瓶颈在应用的并发能力。
还有一类 502 来自上游主动拒绝:日志里是 recv() failed (104: Connection reset by peer) while reading response header from upstream。上游收到了请求,但在返回响应头之前把连接重置了。常见于上游应用崩溃重启的瞬间、或者上游的反向代理配置里 keepalive 连接数耗尽。排查时看上游应用自己的日志,往往能找到对应的异常堆栈。
最后说一个排查顺序,照着走基本不会绕路:先看 Nginx 错误日志定性,再 ss 看端口、直连上游测响应,最后看上游应用日志找根因。502 从来不是 Nginx 的错,它只是那个把坏消息带回来的人。把重启 Nginx 的力气省下来,去修真正出问题的那一环。
- 点赞
- 收藏
- 关注作者
评论(0)