引子
Nginx作为最受欢迎的Web服务器之一,偶尔也会给运维同学出点难题。其中"Connection refused"(连接被拒绝)这个错误就像个调皮的捣蛋鬼,常常让人摸不着头脑。本文将通过多个真实场景的完整示例,带你系统性地掌握排查思路和解决方案。
一、先来认识这个错误(错误特征与日志定位)
当你在浏览器看到"ERR_CONNECTION_REFUSED"或Nginx日志中出现类似connect() failed (111: Connection refused)
的记录时,意味着客户端请求无法到达目标服务。这种情况通常发生在:
- 请求被操作系统防火墙拦截
- Nginx监听端口未正确配置
- 后端服务未启动或端口冲突
- 系统资源限制(如文件句柄耗尽)
日志查看技巧:
tail -f /var/log/nginx/error.log
# 过滤特定错误类型
grep "Connection refused" /var/log/nginx/error.log
二、典型场景与解决方案
场景1:Nginx未监听正确端口(配置失误)
# 错误配置示例:监听不存在的端口
server {
listen 8080; # 实际未开放该端口
server_name localhost;
location / {
proxy_pass http://backend;
}
}
# 正确配置验证方法:
ss -tulnp | grep nginx # 查看实际监听端口
解决方法:
- 检查配置文件中的
listen
指令 - 使用
nginx -t
验证配置语法 - 通过
systemctl restart nginx
重新加载配置
场景2:防火墙阻断连接(系统级防护)
# CentOS 7防火墙检查示例
firewall-cmd --list-all # 查看开放端口
# 临时开放80端口
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --reload
# Ubuntu系统使用ufw的示例
ufw allow 80/tcp
ufw reload
深度技巧:
- 使用
telnet
命令测试端口可达性:
telnet your_server_ip 80 # 成功连接会显示空白界面
场景3:反向代理配置错误(后端服务不可达)
# 错误的后端配置示例
location /api {
proxy_pass http://127.0.0.1:3000; # 后端服务未运行
}
# 诊断方法:
curl -v http://127.0.0.1:3000 # 验证后端服务状态
ps aux | grep node # 假设后端是Node.js服务
正确操作流程:
- 启动后端服务并验证独立访问
- 检查代理配置中的IP和端口
- 添加超时配置增强容错:
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
场景4:端口被其他进程占用(资源冲突)
# 查找占用80端口的进程
sudo lsof -i :80
# 强制释放端口(谨慎操作)
sudo kill -9 $(sudo lsof -t -i :80)
# 推荐的安全做法:
sudo ss -tulnp | grep :80 # 查看占用进程详情
预防措施:
- 使用
netstat
定期检查端口占用 - 为Nginx配置独占端口
- 通过systemd服务限制端口绑定
场景5:文件描述符耗尽(系统资源限制)
# 查看当前限制
ulimit -n
# 临时提升限制(重启失效)
ulimit -n 65535
# 永久配置方法(CentOS示例):
echo "nginx soft nofile 65535" >> /etc/security/limits.conf
echo "nginx hard nofile 65535" >> /etc/security/limits.conf
监控技巧:
watch -n 5 "cat /proc/$(pgrep nginx)/limits" # 实时监控限制状态
场景6:SELinux安全策略限制(隐形的访问控制)
# 检查SELinux状态
getenforce # 返回Enforcing表示已启用
# 临时禁用(不推荐)
setenforce 0
# 正确解决方法:
# 1. 查询拒绝日志
grep nginx /var/log/audit/audit.log | audit2allow
# 2. 生成并应用新策略
grep nginx /var/log/audit/audit.log | audit2allow -M nginxpolicy
semodule -i nginxpolicy.pp
三、进阶排查工具包(专业运维必备)
- 网络诊断三板斧:
# 路由追踪
traceroute your_server_ip
# 数据包捕获
tcpdump -i eth0 port 80 -w capture.pcap
# 连接状态统计
netstat -an | grep :80 | awk '{print $6}' | sort | uniq -c
- 压力测试验证:
# 使用ab工具测试并发
ab -n 1000 -c 100 http://yourserver.com/
- 配置检查清单:
- [ ] 监听地址是否为0.0.0.0
- [ ] 防火墙规则是否正确
- [ ] 后端服务健康状态
- [ ] 系统资源监控数据
四、技术方案对比分析
解决方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
防火墙配置调整 | 即时生效,操作简单 | 可能降低安全性 | 临时调试或内部环境 |
端口冲突解决 | 彻底解决问题 | 需要停服务影响业务 | 生产环境紧急修复 |
SELinux策略调整 | 兼顾安全与功能性 | 配置复杂度高 | 安全要求较高的生产环境 |
资源限制调整 | 预防性措施 | 需要服务器重启才能完全生效 | 高并发场景预先配置 |
五、避坑指南与最佳实践
- 配置管理金科玉律:
- 使用版本控制系统管理Nginx配置
- 每次修改前执行
nginx -t
- 采用灰度发布策略更新配置
- 监控预警必备项:
- 端口监听状态
- 活跃连接数
- 文件描述符使用率
- 后端服务响应时间
- 灾难恢复预案:
# 快速回滚脚本示例
#!/bin/bash
NGINX_CONF="/etc/nginx/nginx.conf"
BACKUP_DIR="/etc/nginx/backup/"
# 回滚到最近备份
cp ${BACKUP_DIR}/nginx.conf.latest ${NGINX_CONF}
systemctl restart nginx
六、总结与展望
通过本文的详细拆解,我们建立了从基础到进阶的完整排查体系。实际工作中,遇到"Connection refused"时需要保持冷静,按照以下步骤系统排查:
- 定位错误发生层级(客户端、网络、Nginx、后端服务)
- 使用工具验证端口可达性
- 逐层检查配置有效性
- 分析系统资源限制
- 查看安全策略影响
未来随着云原生技术的发展,这类问题可能会被服务网格(Service Mesh)等新技术解决,但扎实的基础排查能力仍然是每个运维人员的立身之本。