“connect() failed (111: connection refused)”表示nginx向upstream发起tcp连接时收到rst包,根本原因是目标ip和端口无服务监听或被拦截,需分层排查:先验证upstream地址(如localhost优先解析为::1导致ipv6不匹配)、检查服务实际监听地址(ss -tlnp)、测试本地tcp连通性(nc -zv)、确认dns解析与防火墙规则,并排除健康检查熔断等配置干扰。

看到 connect() failed (111: Connection refused) 不代表后端一定挂了,它只说明 Nginx 在尝试建立 TCP 连接时被目标地址明确拒绝。真正原因可能藏在上游配置、网络栈、DNS 或内核行为里,需要分层验证。
先盯住 upstream 地址和协议版本
日志里 upstream: "http://[::1]:17000/..." 这样的 IPv6 回环地址是高频诱因。Linux 系统若启用 IPv6(ip addr 显示 inet6 ::1/128),Nginx 解析 localhost 会优先选 ::1,但后端服务可能只监听 127.0.0.1 或 0.0.0.0。
- 检查 upstream 配置中是否用了
localhost—— 改成127.0.0.1强制走 IPv4 - 确认后端服务监听地址:
ss -tlnp | grep :17000,看它是绑定在*:17000、127.0.0.1:17000还是::1:17000 - 如果必须支持 IPv6,确保后端也监听
[::1]或::,且防火墙放行
验证连接动作本身是否可达
别只信日志文字,要在 Nginx 所在机器上亲手试一次连接,绕过 DNS 和配置层:
- 用
nc -zv 127.0.0.1 17000测试 TCP 握手是否成功;失败则说明端口没开或被拦截 - 用
curl -I http://127.0.0.1:17000/health模拟真实 HTTP 请求,观察返回码和响应头 - 若用域名(如
backend.example.com),先跑nslookup backend.example.com和dig +short backend.example.com,确认解析出的 IP 是预期的,且不是空或错误记录
查清谁在“拒绝”——是服务、防火墙还是内核?
Connection refused 的本质是对方 TCP 栈发回 RST 包,触发方可能是:
-
后端进程未运行:
systemctl status your-app或ps aux | grep :17000看进程是否存在 - 端口被占用但服务未监听:比如另一个程序占了 17000,但没启动 HTTP 服务,此时连 telnet 都不通
-
本地防火墙拦截 outbound:检查
iptables -L OUTPUT -n -v或nft list chain inet filter output,确认没 DROP 规则 - 云平台安全组/ACL 出方向限制:尤其注意 ECS 或 K8s Node 上的 egress 规则是否允许目标 IP+端口
留意健康检查与熔断机制的干扰
即使后端正常,Nginx 也可能因配置把节点标记为“不可用”,导致后续请求全报 111:
- 检查 upstream 块中是否设了
max_fails=3 fail_timeout=30s,再查 error.log 里是否有连续失败记录 - 运行
nginx -T | grep -A 10 "upstream your_name"确认生效配置,避免 reload 后缓存未更新 - 临时注释掉
max_fails和fail_timeout,reload 后重试,观察是否恢复











