午夜惊魂:用 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命令获取指定目录的磁盘使用率,通过awk和sed处理输出,去掉百分号,只保留数字。 - 第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 脚本:
- 登录 Hey Cron 的 Web 界面。
- 选择你的服务器。
- 点击"添加任务"。
- 输入任务名称,例如"磁盘空间清理"。
- 在"命令"字段中输入
/path/to/cleanup_logs.sh。 - 在"时间"字段中输入
0 3 * * *。 - 保存任务。
通过 Hey Cron,你可以更直观地看到任务的执行情况,包括日志输出、执行状态等,而且 Hey Cron 还支持任务的版本控制和回滚,这在多服务器环境下尤为有用。
总结与思考
通过这个实战案例,你不仅学会了如何使用 Shell 脚本编写定时任务来解决服务器磁盘空间不足的问题,还了解了如何通过 Hey Cron 简化定时任务的管理和监控。在实际生产环境中,合理使用自动化工具可以大大提高系统的稳定性和运维效率。当然,定时任务只是自动化运维的一部分,还有更多工具和方法值得你去探索和实践。
希望这个案例能给你带来一些启发,让你在未来的运维工作中更加得心应手。如果你对 Hey Cron 感兴趣,不妨试试看,它可能会成为你运维工具箱中的又一利器。
祝你夜夜安眠,远离午夜惊魂!