午夜惊魂:用 Shell 脚本和 Hey Cron 解决服务器定时报警

午夜惊魂:用 Shell 脚本和 Hey Cron 解决服务器定时报警

凌晨3点,手机突然"叮"了一声,是服务器发来的报警邮件。当时的我,正沉浸在梦乡,被这突如其来的邮件吓得魂飞魄散。不只是我,几乎所有运维人员都有过类似的经历。服务器在无人监控的夜半三更突然报警,可能是由于磁盘空间不足、内存溢出、或者是某个服务挂掉了。这种时候,你当然希望能快速响应并解决问题,但更理想的状况是,服务器能在问题发生前就自动处理好,避免夜间惊扰。今天,我们就来探讨一个使用 Shell 脚本和定时任务(Cron Job)解决这类问题的实战案例,确保你能在安静的夜晚睡个好觉。

想象一下,你的网站每天都有大量的访问记录和日志数据写入磁盘,如果没有定期清理,磁盘空间迟早会被占满,导致服务器崩溃。为了避免这种情况,我们需要一个脚本,能够定期检查磁盘空间,并在达到某个阈值时自动清理旧的日志文件,同时发送报警邮件通知管理员。这个任务不仅仅是简单的脚本编写,还需要确保它能在特定的时间点自动执行,这就用到了我们的老朋友------Cron。

业务场景分析

假设你有一个 Web 服务器,每天都会生成大量的日志文件,存放在 /var/log/ 目录下。这些日志文件随着时间的积累,会逐渐占用大量的磁盘空间。一旦磁盘空间达到 80% 以上,服务器可能会出现性能下降,甚至无法正常运行。因此,我们希望编写一个 Shell 脚本,每天凌晨3点自动检查磁盘空间,并在磁盘空间超过 80% 时删除 30 天前的日志文件,同时发送报警邮件通知管理员。

编写 Shell 脚本

首先,我们需要编写一个 Shell 脚本来检查磁盘空间,并在必要时执行清理操作。创建一个文件 cleanup_logs.sh,并赋予其执行权限:

bash 复制代码
#!/bin/bash

# 定义日志文件目录
LOG_DIR="/var/log/"

# 定义磁盘空间阈值(80%)
THRESHOLD=80

# 获取当前磁盘使用率
CURRENT_USAGE=$(df -h $LOG_DIR | awk 'NR==2 {print $5}' | sed 's/%//g')

# 检查当前磁盘使用率是否超过阈值
if [ "$CURRENT_USAGE" -gt "$THRESHOLD" ]; then
    # 删除 30 天前的日志文件
    find $LOG_DIR -type f -mtime +30 -exec rm -f {} \;

    # 发送报警邮件
    echo "磁盘空间已达到 $CURRENT_USAGE%,已自动清理 30 天前的日志文件" | mail -s "磁盘空间警告" admin@example.com
fi

解释关键行

  • 第1行 #!/bin/bash:指定脚本使用 Bash 解释器。
  • 第3行 LOG_DIR="/var/log/":定义日志文件的目录。
  • 第5行 THRESHOLD=80:设定磁盘空间的使用率阈值为 80%。
  • 第7行 CURRENT_USAGE=$(df -h $LOG_DIR | awk 'NR==2 {print $5}' | sed 's/%//g'):使用 df -h 命令获取指定目录的磁盘使用率,通过 awksed 处理输出,去掉百分号,只保留数字。
  • 第10行 if [ "$CURRENT_USAGE" -gt "$THRESHOLD" ]; then:判断当前磁盘使用率是否超过阈值。
  • 第12行 find $LOG_DIR -type f -mtime +30 -exec rm -f {} \;:使用 find 命令查找 30 天前的文件,并通过 rm -f 命令删除它们。
  • 第15行 echo "磁盘空间已达到 $CURRENT_USAGE%,已自动清理 30 天前的日志文件" | mail -s "磁盘空间警告" admin@example.com:发送一封包含当前磁盘使用率和清理信息的邮件。

设置定时任务

编写完脚本后,我们需要设置一个定时任务,让这个脚本每天凌晨3点自动运行。打开 Crontab 文件:

bash 复制代码
crontab -e

在文件中添加以下行,保存并退出:

bash 复制代码
0 3 * * * /path/to/cleanup_logs.sh

这里,0 3 * * * 表示每天凌晨3点执行一次任务,/path/to/cleanup_logs.sh 是你刚刚创建的脚本的完整路径。

测试脚本和定时任务

为了确保脚本和定时任务都能正常工作,我们可以手动运行脚本,检查其输出和行为:

bash 复制代码
chmod +x /path/to/cleanup_logs.sh
/path/to/cleanup_logs.sh

如果一切正常,你可以通过 df -h /var/log/ 检查磁盘空间,确认脚本已经成功删除了 30 天前的文件。同时,检查你的邮箱,看看是否收到了报警邮件。

进阶优化

当然,这只是一个基础的解决方案。在实际生产环境中,你可能还需要考虑更多的细节,比如:

  • 日志备份:在删除日志文件之前,可以先将它们备份到其他存储设备,避免数据丢失。
  • 日志压缩:对于不经常需要查看的老日志文件,可以先压缩再删除,节省磁盘空间。
  • 错误处理:添加更多的错误处理逻辑,确保脚本在遇到问题时能够优雅地退出,而不是导致整个服务器出问题。

例如,我们可以优化脚本,添加日志压缩和备份功能:

bash 复制代码
#!/bin/bash

# 定义日志文件目录
LOG_DIR="/var/log/"

# 定义备份目录
BACKUP_DIR="/var/log/backup/"

# 定义磁盘空间阈值(80%)
THRESHOLD=80

# 获取当前磁盘使用率
CURRENT_USAGE=$(df -h $LOG_DIR | awk 'NR==2 {print $5}' | sed 's/%//g')

# 检查当前磁盘使用率是否超过阈值
if [ "$CURRENT_USAGE" -gt "$THRESHOLD" ]; then
    # 创建备份目录(如果不存在)
    mkdir -p $BACKUP_DIR

    # 查找 30 天前的文件,压缩并备份
    find $LOG_DIR -type f -mtime +30 -exec tar -czf $BACKUP_DIR/`basename {}`.tar.gz {} \;

    # 删除已备份的文件
    find $LOG_DIR -type f -mtime +30 -exec rm -f {} \;

    # 发送报警邮件
    echo "磁盘空间已达到 $CURRENT_USAGE%,已自动清理 30 天前的日志文件并备份" | mail -s "磁盘空间警告" admin@example.com
fi

其他实用技巧

环境变量

在某些情况下,你可能希望脚本在特定的环境中运行,比如使用特定的环境变量。你可以在 Crontab 文件中定义这些环境变量:

bash 复制代码
# 设置环境变量
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
LOG_DIR=/var/log/
BACKUP_DIR=/var/log/backup/
THRESHOLD=80

0 3 * * * /path/to/cleanup_logs.sh
日志记录

为了更好地监控脚本的执行情况,你可以在脚本中添加日志记录功能。创建一个日志文件 cleanup_logs.log,并在脚本中记录每一步的操作:

bash 复制代码
#!/bin/bash

# 定义日志文件目录
LOG_DIR="/var/log/"

# 定义备份目录
BACKUP_DIR="/var/log/backup/"

# 定义磁盘空间阈值(80%)
THRESHOLD=80

# 定义日志文件
LOG_FILE="/var/log/cleanup_logs.log"

# 获取当前磁盘使用率
CURRENT_USAGE=$(df -h $LOG_DIR | awk 'NR==2 {print $5}' | sed 's/%//g')

# 检查当前磁盘使用率是否超过阈值
if [ "$CURRENT_USAGE" -gt "$THRESHOLD" ]; then
    # 创建备份目录(如果不存在)
    mkdir -p $BACKUP_DIR
    echo "$(date): 磁盘空间已达到 $CURRENT_USAGE%,开始清理 30 天前的日志文件" >> $LOG_FILE

    # 查找 30 天前的文件,压缩并备份
    find $LOG_DIR -type f -mtime +30 -exec tar -czf $BACKUP_DIR/`basename {}`.tar.gz {} \;
    echo "$(date): 已压缩 30 天前的日志文件" >> $LOG_FILE

    # 删除已备份的文件
    find $LOG_DIR -type f -mtime +30 -exec rm -f {} \;
    echo "$(date): 已删除 30 天前的日志文件" >> $LOG_FILE

    # 发送报警邮件
    echo "磁盘空间已达到 $CURRENT_USAGE%,已自动清理 30 天前的日志文件并备份" | mail -s "磁盘空间警告" admin@example.com
    echo "$(date): 已发送报警邮件" >> $LOG_FILE
else
    echo "$(date): 磁盘空间目前为 $CURRENT_USAGE%,无需清理" >> $LOG_FILE
fi

结合 Hey Cron 进一步简化

虽然 Crontab 是一个非常强大的工具,但它的配置和管理有时会显得繁琐,尤其是在多个服务器上部署定时任务时。这时候,一个更现代化的工具 Hey Cron 就显得非常有用了。Hey Cron 是一个基于 Web 的定时任务管理平台,可以帮助你轻松地管理和监控你的定时任务。

安装 Hey Cron 非常简单,你只需要在服务器上运行以下命令:

bash 复制代码
curl https://heycron.com/install.sh | bash

安装完成后,你可以通过 Hey Cron 的 Web 界面添加和管理定时任务。例如,你可以在 Hey Cron 中添加一个任务,指定每天凌晨3点运行 cleanup_logs.sh 脚本:

  1. 登录 Hey Cron 的 Web 界面。
  2. 选择你的服务器。
  3. 点击"添加任务"。
  4. 输入任务名称,例如"磁盘空间清理"。
  5. 在"命令"字段中输入 /path/to/cleanup_logs.sh
  6. 在"时间"字段中输入 0 3 * * *
  7. 保存任务。

通过 Hey Cron,你可以更直观地看到任务的执行情况,包括日志输出、执行状态等,而且 Hey Cron 还支持任务的版本控制和回滚,这在多服务器环境下尤为有用。

总结与思考

通过这个实战案例,你不仅学会了如何使用 Shell 脚本编写定时任务来解决服务器磁盘空间不足的问题,还了解了如何通过 Hey Cron 简化定时任务的管理和监控。在实际生产环境中,合理使用自动化工具可以大大提高系统的稳定性和运维效率。当然,定时任务只是自动化运维的一部分,还有更多工具和方法值得你去探索和实践。

希望这个案例能给你带来一些启发,让你在未来的运维工作中更加得心应手。如果你对 Hey Cron 感兴趣,不妨试试看,它可能会成为你运维工具箱中的又一利器。

祝你夜夜安眠,远离午夜惊魂!

相关推荐
青山Coding1 小时前
Cesium应用(五):通视分析,解锁三维场景的”无遮挡“视野
前端·cesium
JavaAgent架构师2 小时前
前端AI工程化(三):异步编程与并发控制
前端·人工智能
独泪了无痕2 小时前
利用vue-pdf-embed实现PDF文件的预览
前端·vue.js
Exploring2 小时前
Hola 计算器 v1.0.1 发布:个税计算全面升级,劳务报酬也能算清楚了!
前端
Pan Zonghui2 小时前
个人开源技术博客前端
前端·开源
kyriewen2 小时前
我让AI替我写Git提交信息,老板以为我每天工作16小时
前端·javascript·git
简简单单就是我_hehe2 小时前
高效掌握 JeecgBoot JSelect 组件:外部传参、搜索回显与默认值设置全攻略
前端
闲适达人2 小时前
nginx传递url的获取方案
java·服务器·前端