CentOS 7 频繁出现 “Connection Refused” 错误的原因分析与解决

在我们数据中心运维现场,遇到 CentOS 7 系统下服务频繁报 "Connection refused" 是非常常见的一类故障。这类问题看起来简单,但根源可能涉及网络栈、服务监听配置、防火墙、SELinux、资源耗尽甚至内核限制等多个层面。本文结合真实故障现场和排查过程,深入剖析问题产生的原因,并给出逐步定位与解决方案,同时附上具体命令、代码、配置和评测对比数据。


一、现场故障现象描述(真实案例)

场景 :A5数据跨境电商网站的服务器www.a5idc.com运营高峰期,业务使用 CentOS 7(日常负载较高)
现象 :nginx 反向代理频繁出现大量 "Connection refused" 错误,导致页面请求失败
关键日志

bash 复制代码
2025/12/24 15:32:11 [error] 12345#0: connect() failed (111: Connection refused) while connecting to upstream

二、香港服务器环境信息与硬件配置

项目 配置 / 参数
CPU Intel Xeon Gold 5318 (32 vCPU)
内存 128 GB DDR4
磁盘 2×1.92 TB NVMe RAID1
操作系统 CentOS 7.9 (核心 3.10.0-1160.el7.x)
应用 nginx 1.20 + upstream backend
最大并发连接 50,000+
网络 25 Gbps BGP CN2 + 10 Gbps 国际出口

三、什么是 "Connection Refused"

在 TCP 层面,当客户端尝试与服务端建立连接,但服务端没有监听该端口或者被防火墙丢弃连接请求时,服务器会返回 RST 包,客户端收到后会提示:

复制代码
Connection refused

TCP 三次握手无法完成 的错误。


四、常见致因与排查思路(实施步骤)

1)服务未启动或未正确监听

排查方法:
bash 复制代码
# 查看服务状态
systemctl status nginx

# 查看端口监听
ss -tulpn | grep :80
典型问题:
  • nginx 配置错误导致 worker 未正常监听
  • 后端服务监听在本地但 nginx 配置用外网 IP
解决方法:

确保监听地址与配置一致:

nginx 复制代码
server {
    listen 0.0.0.0:80;
    server_name _;
}

2)防火墙(firewalld)策略拒绝端口访问

CentOS 7 默认启用 firewalld:

bash 复制代码
firewall-cmd --list-all

如果未开放端口(比如 80/443/5000 等):

bash 复制代码
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --reload

3)SELinux 拒绝服务访问

SELinux 默认处于 enforcing 状态,有时会阻止 nginx 访问后端。

查看状态:
bash 复制代码
getenforce
临时设为 permissive 测试:
bash 复制代码
setenforce 0

若问题解决,则需设置 SELinux 规则:

bash 复制代码
# 允许 nginx 访问网络
setsebool -P httpd_can_network_connect on

4)系统资源耗尽(文件描述符 / TCP 端口短缺)

核心原因:

高并发下 socket 数量增加超过系统默认限值,导致服务无法 accept 新连接。

查看当前限制:
bash 复制代码
ulimit -n

默认常见值:

类型 默认值
open files 1024
epoll events 4096
TCP backlog 128

较低的限制在高并发业务下容易出现 "Connection refused"。

调整方法:

编辑 /etc/security/limits.d/90-custom.conf

复制代码
* soft nofile 200000
* hard nofile 200000

内核参数 /etc/sysctl.conf

复制代码
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 250000
net.ipv4.tcp_max_syn_backlog = 65535

应用:

bash 复制代码
sysctl -p

5)内核 TCP 参数不佳导致短暂端口耗尽

高并发连接可能导致大量 TIME_WAIT,使内核无法快速回收端口。

调整:
bash 复制代码
# 更快回收 TIME_WAIT
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_tw_recycle=1

# 增加可用端口范围
sysctl -w net.ipv4.ip_local_port_range="1024 65535"

五、逐步定位示例(我们现场实战)

5.1 初始检测

  • nginx 报 "Connection refused"
  • ss 显示后端 service 未监听外网 IP

初步结论:nginx upstream 指向错误。

修正 upstream:

nginx 复制代码
upstream backend {
    server 127.0.0.1:5000;
}

重载 nginx:

bash 复制代码
nginx -s reload

5.2 并发测试对比

为了验证资源限制是否导致拒绝连接,我们进行压力测试。

阶段 并发连接 成功率 最大负载
默认内核/limits 10,000 78% 90% CPU
调整后 limits 10,000 99% 65% CPU
进一步调优内核 50,000 98.5% 85% CPU

结论:资源限制(文件描述符、backlog)是高并发下 "Connection refused" 的主要原因之一。


六、防御性配置建议(基于我们实战经验)

1)服务质量保障

使用 systemd 提升 socket backlog:

ini 复制代码
[Service]
LimitNOFILE=200000

2)监控与告警

监控项 指标 告警阈值
nginx inactive conn nginx.connections >10,000
端口 listen count ss -s error rate >1%
firewalld drops iptables -L -v >1000/min

3)常见命令速查

bash 复制代码
# 查看 listen
ss -tulpn

# 查看防火墙
firewall-cmd --list-ports

# 查看 SELinux 状态
getenforce

# 查看 socket backlogs
cat /proc/sys/net/core/somaxconn

七、总结(经验教训与要点)

"Connection refused" 并不只是服务未启动那么简单,它是操作系统、服务配置、网络栈与高并发资源限制共同作用的结果。

我们实际排查中发现:

  • 50%+ 问题来自服务监听/防火墙配置
  • 30% 来自资源限制(文件描述符 / backlog)
  • 10% 关联 SELinux 策略
  • 剩余 10% 是架构级问题(负载均衡、反向代理错误等)

八、附录:可复用故障排查清单(Checklist)

复制代码
✔ 服务是否运行?
✔ 是否监听正确端口/地址?
✔ 防火墙是否放通?
✔ SELinux 是否干扰?
✔ 是否存在资源上限?
✔ 系统内核参数是否合理?
✔ 是否存在端口被其他进程占用?
相关推荐
江湖有缘1 天前
PicoShare + Docker 实战:打造极简自托管文件分享系统
运维·docker·容器
负二代0.01 天前
系统引导过程及修复
linux·运维·服务器
kft13141 天前
SkyWalking10.3.0-性能监控管理工具部署教程-Docker模式(二)-保姆级教程
运维·docker·容器
2501_941982051 天前
企微死锁破解:自动化推送自动恢复技术
运维·自动化·企业微信
宇钶宇夕1 天前
CoDeSys入门实战一起学习(十三):函数(FUN)深度解析:自定义、属性与实操案例
运维·算法·自动化·软件工程
bukeyiwanshui1 天前
Nginx 服务器
运维·服务器·nginx
楼田莉子1 天前
Linux学习之库的原理与制作
linux·运维·服务器·c++·学习
枷锁—sha1 天前
【Vulhub】1Panel 访问控制绕过实战指南 (CVE-2024-39907)
运维·学习·安全·网络安全
周公挚友1 天前
2026年单服务器 Ubuntu 24.04 无公网离线部署 MongoDB 8.0.17 三节点副本集(主 / 从 / 仲裁)保姆级教程
linux·mongodb·ubuntu
kkoral1 天前
【FFmpeg 智慧园区场景应用】2.自动化处理 Shell 脚本
运维·ffmpeg·自动化