本文目录导读:

针对PHP项目磁盘空间不足,可以提前设置监控告警 + 自动清理策略,避免业务中断,以下是完整的解决方案,从监控告警到自动清理,覆盖常见场景。
监控方案(提前告警)
方案1:Linux Shell脚本 + Cron(推荐)
创建一个监控脚本 disk_warn.sh:
#!/bin/bash
# 配置
WARN_THRESHOLD=80 # 告警阈值(使用率%)
CRITICAL_THRESHOLD=90 # 严重告警
EMAIL=admin@example.com
LOG_FILE="/var/log/disk_monitor.log"
# 检查磁盘使用率
USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$USAGE" -ge "$WARN_THRESHOLD" ]; then
# 获取占用最大目录
TOP_DIR=$(du -sh /data/* /tmp /var/log 2>/dev/null | sort -rh | head -5)
if [ "$USAGE" -ge "$CRITICAL_THRESHOLD" ]; then
# 严重级别:发送邮件+记录日志
echo "[CRITICAL] 磁盘使用率已达 ${USAGE}%" >> "$LOG_FILE"
echo "WARNING: 磁盘即将满!当前使用率 ${USAGE}%\n\n大文件目录:\n${TOP_DIR}" | mail -s "[紧急] 服务器磁盘空间不足" "$EMAIL"
else
# 警告级别
echo "[WARN] 磁盘使用率已达 ${USAGE}%" >> "$LOG_FILE"
echo "WARNING: 磁盘使用率 ${USAGE}%\n\n大文件目录:\n${TOP_DIR}" | mail -s "[警告] 服务器磁盘空间将满" "$EMAIL"
fi
fi
设置Cron(每1小时检查):
# 编辑 crontab crontab -e # 添加以下行(每小时检查) 0 * * * * /usr/local/bin/disk_warn.sh # 或每10分钟检查一次 */10 * * * * /usr/local/bin/disk_warn.sh
方案2:PHP内置检查(适用于共享主机或特殊环境)
在关键的PHP入口文件(如 index.php 或常驻进程)添加检查:
<?php
// 磁盘监控函数
function checkDiskSpace($alertThreshold = 80) {
$path = '/'; // 检查根目录(也可改为项目目录)
$totalSpace = disk_total_space($path);
$freeSpace = disk_free_space($path);
if ($totalSpace > 0) {
$usedPercent = round((1 - $freeSpace / $totalSpace) * 100);
if ($usedPercent >= $alertThreshold) {
// 触发的告警操作
$logMsg = sprintf(
"[ALERT] 磁盘使用率: %d%% | 总空间: %s | 可用: %s",
$usedPercent,
formatBytes($totalSpace),
formatBytes($freeSpace)
);
// 1. 写入日志
error_log($logMsg, 3, '/var/log/php_disk.log');
// 2. 发送邮件(需要配置mail函数)
// mail('admin@example.com', 'Disk Alert', $logMsg);
// 3. 调用清理脚本(可选)
// shell_exec('/usr/local/bin/cleanup.sh');
return false;
}
}
return true;
}
// 工具函数:格式化字节
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
return round($bytes / pow(1024, $pow), $precision) . ' ' . $units[$pow];
}
// 调用检查
checkDiskSpace();
注意:直接在Web请求中执行可能引起延迟,建议放在后台进程、队列消费或CLI脚本中。
方案3:使用专业监控工具
推荐工具(均可集成告警,无需自己写脚本): | 工具 | 特点 | 告警方式 | |------|------|----------| | Zabbix | 企业级,支持磁盘发现 | 邮件、钉钉、微信 | | Prometheus + Node Exporter | 云原生,可视化好 | 告警管理器 | | Netdata | 轻量,即装即用 | 邮件、Slack | | 云端监控 | 阿里云/腾讯云自带 | 短信、电话 |
清理方案(自动或手动)
根据磁盘空间占用原因,针对性清理:
清理PHP日志文件(最常见)
# 清理访问日志/错误日志(保留最近3天日志)
find /var/log/php* -type f -name "*.log" -mtime +3 -delete
# 或按大小分割日志(配置logrotate)
cat > /etc/logrotate.d/php <<EOF
/var/log/php*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
}
EOF
清理Session文件(如果有大量无效session)
# 清理30天以上的session文件 find /tmp/sess_* -type f -mtime +30 -delete
清理上传缓存/临时文件
常见占用目录:
upload_tmp_dir(php.ini配置)- 图片缩略图缓存
- 调试文件、dump文件
# 清理临时上传文件 find /tmp -name "php*" -type f -mtime +1 -delete # 清理项目缓存目录(如Laravel的storage/framework/cache) rm -rf /path/to/project/storage/framework/cache/data/*
清理数据库慢查询日志、二进制日志(MySQL)
-- MySQL 二进制日志清理 PURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY; -- 清理慢查询日志(保留最近5天的) truncate mysql.slow_log;
自动清理脚本(组合方案)
创建 /usr/local/bin/auto_cleanup.sh:
#!/bin/bash
# 日志清理函数
clean_php_logs() {
echo "清理PHP日志..."
find /var/log/php* -name "*.log" -mtime +7 -delete
find /var/log/nginx -name "*.log" -mtime +7 -delete
}
# 清理临时文件
clean_temp() {
echo "清理临时文件..."
find /tmp -name "php*" -type f -mtime +2 -delete
find /tmp -name "sess_*" -type f -mtime +7 -delete
}
# 清理项目缓存
clean_project_cache() {
echo "清理项目缓存..."
PROJECT_DIR="/data/www/myproject"
if [ -d "$PROJECT_DIR/storage/framework/cache" ]; then
rm -rf "$PROJECT_DIR/storage/framework/cache/data/*"
fi
}
# 执行清理
clean_php_logs
clean_temp
clean_project_cache
# 记录清理后的磁盘状态
df -h / >> /var/log/cleanup_history.log
设置Cron自动执行:
# 每天凌晨3点执行清理 0 3 * * * /usr/local/bin/auto_cleanup.sh
长期预防策略
| 策略 | 实施方法 |
|---|---|
| 日志轮转 | 配置 logrotate,设置保留天数/大小 |
| 文件上传限制 | 在 php.ini 设置 upload_max_filesize=50M,限制单文件大小 |
| 监控阈值预告 | 设置多个告警等级(如 70%警告、85%紧急、95%停机) |
| 定期分析磁盘 | 每月查看大文件:du -sh /* 2>/dev/null \| sort -rh \| head -15 |
| 容器化(高级) | 使用Docker限制日志大小:--log-opt max-size=10m --log-opt max-file=5 |
紧急处理(磁盘已满且无法写入)
如果磁盘已满到无法写入日志或脚本,直接手动操作:
# 1. 查看哪个目录最大 du -sh /* | sort -rh | head -10 # 2. 清理最大的日志文件 > /var/log/nginx/access.log # 直接清空文件(比删除更安全) # 3. 清理docker日志(如果有) docker system prune -af --volumes # 4. 如果是inode满了(文件数过多) df -i # 查看inode使用率 # 清理小文件:find /tmp -type f -delete
总结推荐方案
每天 凌晨 3点 → 自动清理脚本(日志/缓存/临时文件)
每 30分钟 → 磁盘检查脚本(使用率 > 80% 发邮件告警)
每月 1号 → 手动检查大文件 + 优化策略
这样组合可以做到:日常自动清理大部分空间 + 提前告警异常增长 + 定期深度优化,基本能避免磁盘满导致的PHP服务中断。