
在我们数据中心运维现场,遇到 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 是否干扰?
✔ 是否存在资源上限?
✔ 系统内核参数是否合理?
✔ 是否存在端口被其他进程占用?