应监控 nginx 主进程 fd 使用率,当超过 soft limit 的 85% 时触发告警:先用 pgrep 获取主进程 pid,再统计 /proc/pid/fd/ 下链接数,结合 /proc/pid/limits 中 max open files 值计算使用率,超阈值则通过 logger 记录并调用通知命令。

Linux 下 Nginx 文件描述符(file descriptor,简称 fd)使用率过高,容易引发 502、连接拒绝、worker 进程异常退出等问题。监控和告警的关键在于:实时获取 Nginx 主进程打开的 fd 数量,对比系统限制或自定义阈值,触发通知(如邮件、企业微信、钉钉等)。下面用 Shell 脚本实现轻量、可靠、可落地的监控告警逻辑。
获取 Nginx 主进程的当前 fd 使用数
Nginx 主进程(master process)是 fd 的主要持有者,worker 进程通常共享部分 fd(如监听套接字),但统计主进程 fd 更稳定且避免重复计数。可通过 /proc/<pid>/fd/</pid> 目录下的链接数量获取:
- 先用
pgrep -f "nginx: master process"或pidof nginx获取主进程 PID(注意排除 worker) - 再执行
ls -1 /proc/<pid>/fd/ 2>/dev/null | wc -l</pid>统计实际打开的 fd 数 - 为防 PID 变化或进程已退出,建议加判断:
[[ -d "/proc/$pid/fd" ]] && ...
获取系统级 fd 限制并计算使用率
Nginx 实际可用 fd 上限取决于:系统全局限制(fs.file-max) 和 nginx 用户的 ulimit -n(soft limit)。生产中更应关注后者,因为 Nginx 启动时受其运行用户(如 www-data、nginx)的 soft nofile 限制。
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
- 查 nginx 用户的 soft limit:
grep "nofile" /proc/$(pgrep -f "nginx: master process")/limits 2>/dev/null | awk '{print $4}' - 若无法读取 proc limits(如容器环境),可 fallback 到
su -c 'ulimit -n' -s /bin/sh nginx(需 sudo 权限) - 使用率 = 当前 fd 数 ÷ soft limit,超过 85% 即可告警(阈值可配置)
编写可定时执行的告警脚本
以下是一个最小可用版本(保存为 /opt/scripts/nginx-fd-check.sh):
#!/bin/bash
NGINX_USER="nginx" # 根据实际用户修改
ALERT_THRESHOLD=85
ALERT_FILE="/tmp/nginx_fd_alerted"
<h1>获取主进程 PID</h1><p>PID=$(pgrep -f "nginx: master process" | head -n1)
if [[ -z "$PID" ]]; then
echo "$(date): Nginx master not found" >&2
exit 1
fi</p><h1>获取当前 fd 数</h1><p>FD_COUNT=$(ls -1 "/proc/$PID/fd/" 2>/dev/null | wc -l)
if [[ "$FD_COUNT" -eq 0 ]]; then
echo "$(date): No fds found for PID $PID" >&2
exit 1
fi</p><h1>获取 soft nofile limit</h1><p>LIMIT=$(grep "Max open files" "/proc/$PID/limits" 2>/dev/null | awk '{print $4}')
if [[ -z "$LIMIT" || "$LIMIT" = "0" ]]; then
LIMIT=$(su -c 'ulimit -n' -s /bin/sh "$NGINX_USER" 2>/dev/null)
fi</p><p>if [[ -z "$LIMIT" ]]; then
echo "$(date): Cannot determine fd limit" >&2
exit 1
fi</p><h1>计算使用率</h1><p>USAGE=$((FD_COUNT * 100 / LIMIT))
if [[ "$USAGE" -ge "$ALERT_THRESHOLD" ]]; then
if [[ ! -f "$ALERT_FILE" || "$(find "$ALERT_FILE" -mmin +30)" ]]; then
echo "$(date): ALERT! Nginx fd usage: ${USAGE}% ($FD_COUNT/$LIMIT)" | logger -t nginx-fd</p><h1>此处插入你的通知命令,例如:</h1><pre class="brush:php;toolbar:false;"># echo "Nginx fd ${USAGE}%!" | mail -s "Nginx FD Alert" admin@example.com
# 或调用企业微信 webhook curl ...
touch "$ALERT_FILE"fi else
低于阈值,清除告警标记(允许下次触发)
[[ -f "$ALERT_FILE" ]] && rm -f "$ALERT_FILE" fi
部署与验证
将脚本加入 crontab 每 2 分钟检查一次:
chmod +x /opt/scripts/nginx-fd-check.sh-
crontab -e添加:*/2 * * * * /opt/scripts/nginx-fd-check.sh >/dev/null 2>&1 - 手动测试:临时降低 nginx 用户 limit(
sudo prlimit --nofile=100 $(pgrep nginx)),观察是否触发告警 - 日志可通过
journalctl -t nginx-fd或tail /var/log/messages查看
不复杂但容易忽略:务必确保脚本运行用户有权限读取 /proc/<pid>/fd/</pid> 和 /proc/<pid>/limits</pid>,在容器或 SELinux 环境中可能需要额外授权。










