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 是否干扰?
✔ 是否存在资源上限?
✔ 系统内核参数是否合理?
✔ 是否存在端口被其他进程占用?
相关推荐
饭九钦vlog2 小时前
银河麒麟修复openssh升级脚本
linux·运维
航Hang*3 小时前
第1章:初识Linux系统——第13节:总复习②
linux·笔记·学习·centos
Amy_au3 小时前
Linux week 01
linux·运维·服务器
dblens 数据库管理和开发工具3 小时前
Git 指令大全(全干货版)
运维·git·ubuntu
KingRumn3 小时前
DBUS源码剖析之DBusMessage数据结构
linux·服务器·数据结构
bst@微胖子3 小时前
Linux下排查网络偶现超时问题
linux·网络·dubbo
阿豪只会阿巴3 小时前
【多喝热水系列】从零开始的ROS2之旅——Day3
linux·笔记·ubuntu·ros2
OpenMiniServer3 小时前
JsonKV协议技术文档
linux·服务器·网络
小鹏linux4 小时前
【linux】进程与服务管理命令 - chkconfig
linux·运维·服务器