用心打造
VPS知识分享网站

Nginx报connect() failed (111: Connection refused),上游连接解决方法

本文于 2026-09-17 08:17 更新,部分内容具有时效性,如有失效,请留言

Nginx 访问上游时出现 connect() failed (111: Connection refused) while connecting to upstream,说明连接在建立阶段就被拒绝。它与连接超时不同,最常见的原因是上游没有监听目标地址和端口,或者 Nginx 所在网络访问了错误的回环地址。

不要先把 proxy_connect_timeout 调大。连接已被明确拒绝时,延长超时不会让不存在的监听者出现,反而会掩盖真正的地址、端口或启动顺序问题。

Nginx反向代理连接上游服务被拒绝的网络示意图

从错误日志确认实际上游地址

先提取完整错误上下文:

sudo grep -F 'connect() failed (111: Connection refused)' /var/log/nginx/error.log | tail -50
sudo nginx -T 2>&1 | less

重点记录日志里的 upstreamhostrequest 和时间。upstream 才是 Nginx 真正尝试连接的地址;配置文件里写了一个域名,不代表运行时一定解析到预期 IP。

先把故障请求对应到具体的 serverlocationproxy_pass,再修改配置。 同一台机器可能同时代理多个端口,不能只看浏览器返回的 502 就判断所有后端都已停止。

检查上游服务是否真的在监听

在上游所在的系统或容器中检查监听:

sudo ss -ltnp
sudo systemctl status app.service --no-pager
sudo journalctl -u app.service --since '15 minutes ago' --no-pager

假设 Nginx 连接 127.0.0.1:8000,可进一步过滤并直接访问:

sudo ss -ltnp '( sport = :8000 )'
curl -v --max-time 5 http://127.0.0.1:8000/health

服务显示 active 不等于端口已经监听,进程也可能只监听 IPv6、另一个端口或特定内网地址。验收必须同时看到正确监听地址和健康请求成功。

核对proxy_pass中的协议、地址和端口

Nginx 官方文档说明,proxy_pass 需要给出协议和上游地址,并可附带端口或 URI。例如:

location /api/ {
    proxy_pass http://127.0.0.1:8000/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

检查端口是否与应用配置一致,并确认后端究竟提供 HTTP 还是 HTTPS。把 HTTPS 服务写成 http://,或把 URI 尾部斜杠改错,会产生不同故障,不能只为消除当前日志而随意替换。

若后端使用 Unix Socket,官方支持如下形式:

proxy_pass http://unix:/run/app/app.sock:;

Socket 路径必须对 Nginx worker 可见且有访问权限;它与 TCP 端口方案不能混写。

容器中的127.0.0.1不是宿主机

Nginx 运行在 Docker 容器时,127.0.0.1 指向 Nginx 容器自身,不是宿主机,也不是另一个应用容器。Compose 项目应让两个服务加入同一用户定义网络,并用服务名访问:

services:
  nginx:
    networks: [appnet]
  backend:
    networks: [appnet]
networks:
  appnet: {}

对应配置可以使用 proxy_pass http://backend:8000;。进入 Nginx 容器验证名称和端口:

docker exec nginx getent hosts backend
docker exec nginx curl -v --max-time 5 http://backend:8000/health

宿主机能访问后端,不代表 Nginx 容器拥有同样的网络路径。 需要复现同一网络命名空间中的访问结果。

修复启动顺序和监听范围

应用启动慢时,Nginx 可能先接到请求,而后端仍在初始化。容器的启动顺序只能决定进程创建先后,不能证明服务已经可用,应配置健康检查并让部署系统等待健康状态。

应用只监听 127.0.0.1 时,另一个容器无法访问;改为受控的容器网络地址或 0.0.0.0 后,还要配合防火墙和端口发布策略。不要为了容器互通就把后端端口直接发布到公网。

需要复制相同版本与网络拓扑时,可在 萤光云 建立隔离测试环境,或用按小时计费的 LightNode 验证反向代理切换。测试环境不要放入生产令牌和真实用户数据。

重新加载并完成验收

修改后先检查配置,再平滑加载:

sudo nginx -t
sudo systemctl reload nginx
systemctl is-active nginx
curl -fsS https://example.com/health

同时观察 Nginx 与应用日志,确认请求确实到达预期实例。不要只看首页 200;登录、上传或 API 路径可能落到不同的 location 和上游。

合格的验收结果是上游在设计地址持续监听、Nginx 配置可加载、真实业务路径成功,并且错误日志不再新增连接拒绝。

FAQ

把proxy_connect_timeout改大能解决吗?

不能解决端口无人监听或地址写错。它控制建立上游连接的等待时间,更适合处理连接迟迟没有响应的情况,而不是明确返回拒绝的连接。

为什么重启应用后暂时恢复?

可能是应用曾崩溃、端口未监听,或部署期间存在短暂空窗。应继续检查应用退出原因、健康检查和启动依赖,而不是把定时重启当作修复。

防火墙也会导致Connection refused吗?

拒绝规则可能主动返回错误,但丢弃规则更常表现为超时。先在 Nginx 所在网络中直接测试,再结合防火墙计数和上游监听判断。

温馨提示

排除这类故障的核心是沿着 Nginx 实际使用的地址,从同一网络环境验证监听与健康请求。 修改前保存完整配置,生产变更要保留回滚方案,避免修复连接后又意外暴露后端端口。

赞(0)
未经允许不得转载;国外VPS测评网 » Nginx报connect() failed (111: Connection refused),上游连接解决方法
分享到