先看现象。nginx 反代两台 PHP 后端,每次发版后 error.log 里集中出现 connect() failed (111: Connection refused) while connecting to upstream,持续二十来秒,之后自己恢复,监控上是一道短暂的五零二尖峰。
这类报错背后常见的原因有几处,逐个排除就行。后端进程重启的那几秒端口没有监听,连接直接被内核拒绝。也可能是upstream 没有配置失败重试与摘除,坏节点仍在轮询列表里。
少数情况下是keepalive 复用了重启前建立的连接,对端已经关闭。
不容易想到的是,发布脚本逐台重启但间隔太短,两台同时不可用。
第一件事是确认尖峰只出现在发布时段
grep -c 'Connection refused' /var/log/nginx/error.log
然后看 upstream 里节点是怎么写的
grep -n 'upstream\|server 10\.0' /etc/nginx/conf.d/api.conf
给节点加上失败摘除参数
sed -i 's#server 10.0.3.21:8080;#server 10.0.3.21:8080 max_fails=2 fail_timeout=10s;#' /etc/nginx/conf.d/api.conf && nginx -t && nginx -s reload
发版时先把节点权重置零再重启
sed -i 's#server 10.0.3.21:8080 max_fails#server 10.0.3.21:8080 weight=0 max_fails#' /etc/nginx/conf.d/api.conf && nginx -s reload
改完先别撤,确认这几项。下一次发版期间 error.log 里 Connection refused 条数为零,五零二尖峰消失,重启节点恢复后能自动回到轮询列表。
提醒一点。拒绝连接说明对端根本没在监听,和超时不是一回事;发布流程里加摘流量这一步,比加多少重试都管用。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
