本文目录导读:

在 Laravel 中,清理任务通常使用定时任务(调度任务)来实现,而不是直接用 Linux 的 crontab 写复杂脚本,Laravel 的 schedule 机制本质上还是基于 crontab,但提供了更优雅、更项目内聚的管理方式。
常见需要清理的场景
- 日志文件 -
storage/logs/laravel.log过大 - 会话文件 -
storage/framework/sessions/过期会话 - 缓存文件 - 视图缓存、数据缓存
- 临时上传文件 - 未使用的临时文件
- 数据库过期数据 - 旧日志、软删除数据等
- 活动日志/通知 - 过期的活动记录
实现方式
使用 Laravel 内置的 Schedule(推荐)
在 app/Console/Kernel.php 的 schedule 方法中定义清理任务:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
// 清理过期会话(每天一次)
$schedule->command('session:clean')
->daily();
// 清理模型过期数据(每天凌晨2点)
$schedule->call(function () {
// 删除30天前的日志
ActivityLog::where('created_at', '<', now()->subDays(30))->delete();
// 硬删除软删除超过30天的数据
Post::onlyTrashed()
->where('deleted_at', '<', now()->subDays(30))
->forceDelete();
})->dailyAt('02:00');
// 清理临时文件(每小时)
$schedule->command('telescope:prune --hours=48')
->hourly();
// 使用 Artisan 命令清理(自定义命令)
$schedule->command('logs:clean')
->weekly()
->appendOutputTo(storage_path('logs/cleanup.log'));
}
创建自定义 Artisan 命令
如果清理逻辑复杂,建议创建独立的 Artisan 命令:
php artisan make:command CleanExpiredData
// app/Console/Commands/CleanExpiredData.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class CleanExpiredData extends Command
{
protected $signature = 'app:clean-expired-data
{--days=30 : 保留天数}
{--type=all : 清理类型(logs,sessions,db,all)}';
protected $description = '清理过期数据';
public function handle()
{
$days = $this->option('days');
$type = $this->option('type');
if ($type === 'logs' || $type === 'all') {
$this->cleanLogs($days);
}
if ($type === 'sessions' || $type === 'all') {
$this->cleanSessions();
}
if ($type === 'db' || $type === 'all') {
$this->cleanDatabase($days);
}
$this->info('清理完成!');
}
protected function cleanLogs($days)
{
// 清理 storage/logs 中的旧日志
$logFiles = glob(storage_path('logs/*.log'));
foreach ($logFiles as $file) {
if (filemtime($file) < now()->subDays($days)->timestamp) {
unlink($file);
$this->line("删除日志文件: " . basename($file));
}
}
}
protected function cleanSessions()
{
// Laravel 会自动清理 sessions,但可以手动触发
$this->call('session:clean');
}
protected function cleanDatabase($days)
{
// 清理过期记录
InactiveUser::where('last_login', '<', now()->subDays($days))->delete();
TempUpload::where('created_at', '<', now()->subDay())->delete();
}
}
然后在 Kernel.php 中调度:
$schedule->command('app:clean-expired-data --days=30 --type=all')
->dailyAt('03:00')
->onOneServer(); // 多台服务器时防止重复执行
使用队列任务(适合大批量清理)
对于大量数据清理,建议使用队列,避免阻塞主进程:
// 在 Kernel 中
$schedule->job(new \App\Jobs\CleanExpiredData(['days' => 30]))
->daily()
->withoutOverlapping(60); // 防止重复,锁60分钟
// app/Jobs/CleanExpiredData.php
public function handle()
{
// 分批删除,避免锁表
Post::where('expires_at', '<', now())
->chunkById(100, function ($posts) {
foreach ($posts as $post) {
$post->delete(); // 如果有事件监听
}
});
// 或者使用 each 分批
TempFile::where('created_at', '<', now()->subDay())
->each(function ($file) {
Storage::delete($file->path);
$file->delete();
}, 100);
}
设置 crontab(仅需一行)
在服务器上设置 crontab 即可,不需要为每个任务单独设置 cron:
# 每天执行 Laravel 调度器 * * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Laravel 的 Schedule 会根据你定义的时间频率自动决定何时执行。
最佳实践建议
| 建议 | 说明 |
|---|---|
| 频率合理 | 日志每天清理,临时文件每小时,数据库过期数据每天 |
| 时间选择 | 避免高峰期,建议凌晨02:00-05:00 |
| 防止重叠 | 使用 withoutOverlapping() 防止任务重叠 |
| 监控日志 | 使用 appendOutputTo() 记录执行日志 |
| 测试优先 | 先在测试环境运行 php artisan schedule:test 测试 |
| 分批处理 | 大数据量使用 chunk 或队列,避免内存溢出 |
| 异常处理 | 在命令或 Job 中添加 try-catch 和通知 |
| 多服务器 | 使用 onOneServer() 防止多台服务器重复执行 |
示例:完整的清理策略
protected function schedule(Schedule $schedule)
{
// 每天凌晨3点清理
$schedule->command('queue:prune-failed --hours=48')
->dailyAt('03:00');
// 每周清理旧日志
$schedule->exec('find ' . storage_path('logs') . ' -name "*.log" -mtime +7 -delete')
->weekly()
->onOneServer();
// 每天清理数据库过期数据
$schedule->call(function () {
// 批量删除,记录日志
$deleted = OldRecords::where('created_at', '<', now()->subMonths(6))
->delete();
Log::info("清理了 {$deleted} 条旧记录");
})->dailyAt('04:00')
->withoutOverlapping(60)
->appendOutputTo(storage_path('logs/scheduled-clean.log'));
}
- ✅ 用 Laravel Schedule 管理清理任务(推荐)
- ✅ 创建自定义 Artisan 命令 组织复杂逻辑
- ✅ 设置 crontab 为
* * * * * php artisan schedule:run - ✅ 合理分配频率 和时间,使用
withoutOverlapping - ✅ 测试命令
php artisan schedule:test模拟执行
Laravel 的定时任务机制让清理工作变得非常整洁和可维护,而且可以充分利用 Laravel 的 ORM、事件、队列等功能来安全高效地执行。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播