服务器监控脚本Nginx 版 — 详细操作指南
📋 内容总览
- 磁盘空间检测 + 邮件报警
- 两种方法检测 Nginx 服务状态
- curl 访问 openlab 站点验证
- 完整脚本文件说明
- 脚本部署及验证测试部署
1.磁盘空间检测 + 邮件报警
需求说明
检测服务器根分区剩余空间,如果小于 20GB 则发送邮件报警,要求每天检查一次。
核心命令详解
# 1. 获取根分区可用空间(df 命令) [root@openlab ~]# df /# 输出字段说明: # 第1列 = 文件系统设备名 # 第2列 = 总大小(KB) # 第3列 = 已使用(KB) # 第4列 = 可用空间(KB) ← 我们要取这个值 # 第5列 = 使用百分比 # 第6列 = 挂载点
# 2. 用 awk 提取第4列(Available)
[root@openlab ~]# df / | awk 'NR==2 {print $4}'
# NR==2 表示只处理第2行数据行(跳过表头)
# $4 表示第4列
# 结果单位:KB
# 3. KB 转 GB(除以 1048576 = 1024*1024) [root@openlab ~]# echo "scale=2; 35123456 / 1048576" | bc# scale=2 表示保留2位小数 # bc 是 Linux 计算器命令
# 4. 浮点数比较(bash 不支持直接比较浮点数,用 awk) [root@openlab ~]# awk 'BEGIN { print (33.50 < 20) ? 1 : 0 }'返回 0(不报警) [root@openlab ~]# awk 'BEGIN { print (15.00 < 20) ? 1 : 0 }'
返回 1(需要报警)
# 5. 发送邮件(mail 或 mailx 命令) [root@openlab ~]# yum install -y mailx# 发送邮件的基本格式 echo "邮件内容" | mail -s "邮件主题" 收件人地址
💡 关键:
• df 的可用空间在第 4 列(不是第3列!第3列是已用空间)
• 单位是 KB,需要除以 1048576 换算成 GB
• 浮点数比较要用 awk 或 bc,bash 原生不支持
• 邮件发送前确保安装了 mailx 包并配置了 postfix/sendmail
安装邮件服务postfix
#install postfix mailx -y

启动服务并设置开机自启动

配置定时任务(crontab)
crontab 格式说明
| 字段 | 分 | 时 | 日 | 月 | 周 | 命令 |
|---|---|---|---|---|---|---|
| 范围 | 0-59 | 0-23 | 1-31 | 1-12 | 0-6 | - |
| 本例 | 0 | 8 | * | * | * | /path/to/script.sh |
# 编辑当前用户的 crontab [root@openlab ~]# crontab -e # 在文件末尾追加以下行: 0 8 * * * /usr/local/bin/monitor_nginx.sh >> /var/log/monitor_cron.log 2>&1# 含义:每天早上 8:00 执行一次监控脚本 # 日志追加写入 monitor_cron.log 文件 # 查看 crontab 列表
![]()
💡 常用 crontab :
• * * * * * → 每分钟执行
• */5 * * * * → 每 5 分钟执行
• 0 */2 * * * → 每 2 小时执行
• 30 8 * * 1 → 每周一 8:30 执行
• 0 8 1 * * → 每月 1 号 8:00 执行
2.两种方法检测 Nginx 服务是否运行
需求说明
用两种不同方法检测 Web 服务(Nginx)是否在运行。如果未运行,则启动服务并配置防火墙放行端口。
方法一:进程检测 — pgrep 命令
# pgrep -x nginx:精确匹配名为 "nginx" 的进程 # -x = exact mode,精确匹配进程名(不会匹配到 "nginx-worker" 等) [root@openlab ~]# pgrep -x nginx# 返回 PID 表示进程存在 → 服务正在运行 # 无输出或返回空 → 进程不存在 → 服务未运行 # 在脚本中的用法(结合 if 判断): if pgrep -x nginx > /dev/null 2>&1; then echo "Nginx 正在运行" else echo "Nginx 未运行" fi
| 方法一 vs 方法二 对比 | ||
|---|---|---|
| 对比项 | 方法一:pgrep(进程检测) | 方法二:ss(端口检测) |
| 检测原理 | 查找 nginx 进程是否存在 | 检查 80 端口是否有程序监听 |
| 核心命令 | pgrep -x nginx | ss -tlnp | grep :80 |
| 优点 | 简单直观,不易误判 | 确认端口确实在监听 |
| 缺点 | 进程存在不代表正常响应 | 需配合 grep 过滤 |
| Nginx 特有 | 进程名为 nginx | Apache 用 :80|httpd,Nginx 用 :80|nginx |
方法二:端口检测 — ss 命令
# ss 是 netstat 的替代品 # 参数说明: # -t = TCP 协议 # -l = listening(仅显示监听状态的连接) # -n = numeric(以数字形式显示端口号和地址) # -p = processes(显示监听该端口的进程信息) [root@openlab ~]# ss -tlnp | grep ':80'# 有输出 = 端口 80 正在被 nginx 监听 ✓ # 无输出 = 没有进程监听 80 端口 ✗ # 在脚本中的用法: if ss -tlnp | grep -q ':80.*nginx'; then echo "Nginx 正在监听 80 端口" else echo "Nginx 未监听 80 端口" fi
⚠️ 为什么用 ss 而不是 netstat?
- ss 默认自带、性能强、官方主推;
- netstat 废弃、无预装,需额外安装,仅兼容旧脚本临时使用,日常排查一律用 ss。
Nginx 未运行时的恢复操作
# 启动 Nginx# 配置防火墙(如果 firewall-cmd 可用) [root@openlab ~]# firewall-cmd --permanent --add-service=http # 放行 80 端口 [root@openlab ~]# firewall-cmd --permanent --add-service=https # 放行 443 端口(可选) [root@openlab ~]# firewall-cmd --reload # 重载防火墙规则
![]()
🔴 Nginx vs Apache 在此任务中的差异:
• Apache 进程名:httpd → pgrep 用 pgrep -x httpd
• Nginx 进程名:nginx → pgrep 用 pgrep -x nginx
• 端口过滤:grep ':80.*httpd' → grep ':80.*nginx'
• 启动命令:systemctl start httpd → systemctl start nginx
3.curl 访问 OpenLab 站点验证
需求说明
使用 curl 访问上次作业搭建的 OpenLab 网站:
• 返回 HTTP 200 → 输出 web server is running
• 返回其他状态码 → exit 12(自定义错误码退出)
curl 核心参数详解
| 参数 | 作用 | 示例 |
|---|---|---|
| -s | 静默模式(不显示进度条和错误信息) | curl -s URL |
| -o file | 将内容保存到指定文件 | curl -o /dev/null URL |
| -w format | 输出完成后执行格式化输出 | curl -w "%{http_code}" |
| -k | 忽略 SSL 证书验证(HTTPS 时用) | curl -k https://... |
| -u user:pass | Basic Auth 认证 | curl -u song:pass URL |
| --connect-timeout | 连接超时时间(秒) | curl --connect-timeout 5 URL |
实现代码
# 只获取 HTTP 状态码,不下载页面内容
# -s 静默模式
# -o /dev/null 页面内容丢入黑洞(不保存)
# -w "%{http_code}" 只输出 HTTP 状态码数字
http_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "$WEB_URL")
echo "HTTP 状态码: $http_code"
if [ "$http_code" -eq 200 ]; then
echo "web server is running" # 指定输出文字
else
exit 12 # 指定退出码
fi
各种状态码的含义
| 状态码 | 含义 | 可能原因 |
|---|---|---|
| 200 | 成功 | 网站正常运行 ✓ |
| 301/302 | 重定向 | HTTP 跳转到 HTTPS,用 -L 跟随重定向 |
| 401 | 未授权 | /student 需要 Basic Auth 登录 |
| 403 | 禁止访问 | 目录权限问题 |
| 404 | 页面不存在 | 路径拼写错误或文件不存在 |
| 500 | 服务器内部错误 | Nginx 配置语法错误或后端故障 |
| 000 | 连接失败 | 服务未启动或防火墙拦截 |
任务三的 curl 目标应该是主页 http://www.openlab.com/(不需要认证的路径)
4.完整脚本结构说明
脚本整体流程图
┌─────────────────────────────┐
│ 脚本开始 (main) │
│ 写日志: 监控脚本启动 │
└──────────┬──────────────────┘
│
┌──────┴───────────┐
│ │
▼ ▼
┌────────┐ ┌──────────┐
│ 任务一 │ │ 任务二 │
│磁盘检测 │ │Nginx检测 │
│<20G报警│ │2种方法 │
└───┬────┘ └────┬─────┘
│ │
▼ ▼
┌────────┐ ┌──────────┐
│ 任务三 │◄─────│ 自动恢复 │
│curl检测 │ │启动+防火墙│
│exit 12 │ └──────────┘
└───┬────┘
│
▼
┌─────────────────────────────┐
│ 所有任务完成,写结束日志 │
└─────────────────────────────┘
函数清单
| 函数名 | 功能 | 对应任务 |
|---|---|---|
| check_disk_space() | df 检测磁盘 → bc 转换 GB → 比较阈值 → mail 报警 | 任务一 |
| check_nginx_process() | pgrep -x nginx 检测进程 | 任务二·方法1 |
| check_nginx_port() | ss -tlnp 检测 80 端口 | 任务二·方法2 |
| restart_nginx_with_firewall() | systemctl start nginx + firewall-cmd 放行端口 | 任务二·恢复 |
| check_website() | curl 取状态码 → 200 成功 / 其他 exit 12 | 任务三 |
| main() | 按顺序调用以上所有函数 | 主控 |
5.部署脚本与验证测试部署
步骤 4.1:上传/创建脚本文件
// 将 monitor.sh 上传到服务器的 /root/ 目录 [root@openlab ~]# vim /root/monitor.sh// 将完整的脚本内容粘贴进去后保存退出 // :wq
// 赋予可执行权限 [root@openlab ~]# chmod +x /root/monitor.sh
步骤 4.2:手动运行测试
步骤 4.3:模拟异常情况测试
// 测试场景A:手动停掉 nginx,看任务二能否自动恢复![]()
// 测试场景B:修改阈值让磁盘报警触发(临时改为极大值) // 编辑 monitor.sh,将 DISK_THRESHOLD 改为 99999![]()
邮件发送成功
// 一定记得改回来! [root@openlab ~]# sed -i 's/DISK_THRESHOLD=99999/DISK_THRESHOLD=20/' monitor.sh


openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

# 发送邮件的基本格式
echo "邮件内容" | mail -s "邮件主题" 收件人地址
# 配置防火墙(如果 firewall-cmd 可用)
[root@openlab ~]# firewall-cmd --permanent --add-service=http # 放行 80 端口
[root@openlab ~]# firewall-cmd --permanent --add-service=https # 放行 443 端口(可选)
[root@openlab ~]# firewall-cmd --reload # 重载防火墙规则
// 将完整的脚本内容粘贴进去后保存退出
// :wq
// 赋予可执行权限
[root@openlab ~]# chmod +x /root/monitor.sh
邮件发送成功
// 一定记得改回来!
[root@openlab ~]# sed -i 's/DISK_THRESHOLD=99999/DISK_THRESHOLD=20/' monitor.sh


所有评论(0)