应优先排查文件描述符限制和selinux策略:检查worker进程的max open files是否为1024,若属实需在limits.conf中调高并重启worker;运行getenforce确认selinux是否为enforcing模式,若是则用setenforce 0临时验证,并用audit2why分析avc日志定位拦截点。

遇到 Nginx 报错如 Connection refused、Permission denied (13) 或静默失败(无日志但请求不通),若已排除配置语法、端口占用、后端服务状态等常见原因,就该重点排查文件描述符限制和 SELinux 策略这两类底层系统级冲突。
查文件描述符是否卡住 worker 进程
Nginx worker 进程每处理一个连接、打开一个临时文件、写一条日志,都会消耗一个文件描述符。默认系统限制常为 1024,高并发或大量静态资源场景下极易耗尽,导致新连接被内核直接拒绝(表现为 Connection refused),且错误日志里往往不体现具体原因。
- 确认当前 worker 进程的限制值:
cat /proc/$(pgrep nginx | head -n1)/limits | grep "Max open files"
若显示1024,基本可判定为瓶颈 - 永久提升需两步:在
/etc/security/limits.conf中添加nginx soft nofile 65536nginx hard nofile 65536
(将nginx替换为你实际配置的user指令值) - 重启 worker 进程生效(非 reload):
sudo systemctl kill --signal=SIGQUIT nginx再sudo systemctl start nginx,或直接sudo pkill -f "nginx: worker"让 master 自动拉起新 worker
验 SELinux 是否拦截关键操作
SELinux 在 enforcing 模式下会严格限制 Nginx 进程能访问的路径、端口和网络能力。即使文件权限全对、端口开放、防火墙放行,它仍可能默默拦截——且多数情况下只记 AVC 拒绝日志,不写进 error.log。
- 先看当前模式:
getenforce—— 若返回Enforcing,嫌疑很大 - 临时切换为 permissive 模式验证:
sudo setenforce 0,再测试请求是否恢复;若恢复正常,基本锁定 SELinux - 查具体拦截点:
sudo ausearch -m avc -ts recent | audit2why
或更精准:sudo dmesg -T | grep -i "avc.*nginx" - 常见需放开的策略包括:
• 允许 Nginx 访问网络:sudo setsebool -P httpd_can_network_connect 1
• 允许绑定非标准端口(如 8080):sudo semanage port -a -t http_port_t -p tcp 8080
• 允许读取网站目录(若用非标准路径):sudo semanage fcontext -a -t httpd_sys_content_t "/path/to/web(/.*)?",再restorecon -Rv /path/to/web
联动排查:两者可能同时触发
例如 OOM Killer 因内存不足杀掉后端进程后,Nginx 尝试重连时既可能因 fd 耗尽无法新建 socket,也可能因 SELinux 拦截 connect() 系统调用而报错。此时单看任一维度都不完整。
- 执行
dmesg -T | grep -i "killed process",确认是否有后端(Java/Python/Node)被干掉 - 检查
/var/log/audit/audit.log或journalctl -t kernel | grep avc,交叉比对时间戳与 Nginx 错误发生时刻 - 用
ss -s查当前 socket 总数,结合lsof -p $(pgrep nginx | head -n1) | wc -l看单个 worker 占用量,判断是否接近上限











