引子

Nginx作为最受欢迎的Web服务器之一,偶尔也会给运维同学出点难题。其中"Connection refused"(连接被拒绝)这个错误就像个调皮的捣蛋鬼,常常让人摸不着头脑。本文将通过多个真实场景的完整示例,带你系统性地掌握排查思路和解决方案。


一、先来认识这个错误(错误特征与日志定位)

当你在浏览器看到"ERR_CONNECTION_REFUSED"或Nginx日志中出现类似connect() failed (111: Connection refused)的记录时,意味着客户端请求无法到达目标服务。这种情况通常发生在:

  1. 请求被操作系统防火墙拦截
  2. Nginx监听端口未正确配置
  3. 后端服务未启动或端口冲突
  4. 系统资源限制(如文件句柄耗尽)

日志查看技巧

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  # 查看实际监听端口

解决方法

  1. 检查配置文件中的listen指令
  2. 使用nginx -t验证配置语法
  3. 通过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服务

正确操作流程

  1. 启动后端服务并验证独立访问
  2. 检查代理配置中的IP和端口
  3. 添加超时配置增强容错:
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

三、进阶排查工具包(专业运维必备)

  1. 网络诊断三板斧
# 路由追踪
traceroute your_server_ip

# 数据包捕获
tcpdump -i eth0 port 80 -w capture.pcap

# 连接状态统计
netstat -an | grep :80 | awk '{print $6}' | sort | uniq -c
  1. 压力测试验证
# 使用ab工具测试并发
ab -n 1000 -c 100 http://yourserver.com/
  1. 配置检查清单
  • [ ] 监听地址是否为0.0.0.0
  • [ ] 防火墙规则是否正确
  • [ ] 后端服务健康状态
  • [ ] 系统资源监控数据

四、技术方案对比分析

解决方案 优点 缺点 适用场景
防火墙配置调整 即时生效,操作简单 可能降低安全性 临时调试或内部环境
端口冲突解决 彻底解决问题 需要停服务影响业务 生产环境紧急修复
SELinux策略调整 兼顾安全与功能性 配置复杂度高 安全要求较高的生产环境
资源限制调整 预防性措施 需要服务器重启才能完全生效 高并发场景预先配置

五、避坑指南与最佳实践

  1. 配置管理金科玉律
  • 使用版本控制系统管理Nginx配置
  • 每次修改前执行nginx -t
  • 采用灰度发布策略更新配置
  1. 监控预警必备项
  • 端口监听状态
  • 活跃连接数
  • 文件描述符使用率
  • 后端服务响应时间
  1. 灾难恢复预案
# 快速回滚脚本示例
#!/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"时需要保持冷静,按照以下步骤系统排查:

  1. 定位错误发生层级(客户端、网络、Nginx、后端服务)
  2. 使用工具验证端口可达性
  3. 逐层检查配置有效性
  4. 分析系统资源限制
  5. 查看安全策略影响

未来随着云原生技术的发展,这类问题可能会被服务网格(Service Mesh)等新技术解决,但扎实的基础排查能力仍然是每个运维人员的立身之本。