“Connection refused”(errno 111)表明目标地址和端口无服务监听或被拦截,需立即验证进程状态(systemctl is-active)、端口监听(ss -tlnp)、TCP连通性(telnet/nc),并排查防火墙、DNS、socket路径等干扰项。

看到 error.log 里反复出现 “Connection refused”,基本可以断定后端服务已失联——不是配置错,就是进程挂了。关键不在于查多少遍日志,而在于用对线索、快速验证、精准定位。
盯住日志里的核心信号
“Connection refused”(errno 111)不是偶然报错,而是 TCP 层明确拒绝连接的反馈。它说明 Nginx 尝试建立连接时,目标地址+端口上根本没有服务在监听。这不是超时、不是权限问题、也不是慢响应,是“根本没人应答”。
- 重点看报错行是否带具体 upstream 地址,例如:
connect() failed (111: Connection refused) while connecting to upstream "fastcgi://127.0.0.1:9000"或upstream "http://10.0.2.5:8080" - 检查时间戳是否集中爆发——如果是整点批量出现,可能是定时任务杀进程;如果持续不断,大概率服务已退出且未自动拉起
- 注意是否伴随
no live upstreams——说明所有 backend 都被标记为不可用,故障面已扩大
三步验证,5 分钟确认是否真宕机
别只盯着日志猜,立刻在 Nginx 服务器上执行以下验证:
-
查进程是否存活:运行
systemctl is-active php-fpm(或对应服务名),返回inactive或failed就坐实了 -
查端口是否监听:用
ss -tlnp | grep ':9000'(替换为你实际端口),若无输出,说明监听没起来;注意看 bind 地址是127.0.0.1:9000还是*:9000,前者只允许本地连,后者才可被跨主机访问 -
手动连一下试试:执行
telnet 127.0.0.1 9000或nc -zv 127.0.0.1 9000,显示Connection refused即复现问题,证明链路末端确实不通
排除常见干扰项
有时“Connection refused”是假象,实际另有隐情:
-
防火墙拦截:即使服务在跑,iptables/nftables 可能屏蔽了 outbound 连接,运行
sudo iptables -L OUTPUT -n -v查 OUTPUT 链是否有 DROP 规则 -
DNS 解析失败但配置用了域名:如果 upstream 写的是
backend.example.com,先执行nslookup backend.example.com,返回空或错误 IP 就会导致连接被内核直接拒掉 -
socket 文件路径不一致:fastcgi_pass 指向
unix:/var/run/php/php8.2-fpm.sock,但 PHP-FPM 实际监听的是/run/php/php8.2-fpm.sock(少了个 var),也会报 Connection refused
加个轻量级自动告警(可选)
不想靠人盯日志?加一行脚本就能实现基础监控:
- 每分钟执行:
grep -c "Connection refused" /var/log/nginx/error.log | awk '$1 > 3 {print "ALERT: Backend down at $(date)"}' >> /var/log/nginx/alert.log - 配合 logrotate 按小时切分 error.log,避免误报累积;真正上线建议接入 Prometheus + Alertmanager,用
count_over_time(nginx_error_log_lines{level="error", msg=~".*Connection refused.*"}[5m]) > 3做指标告警


















