任务调度

最后更新: 2026-01-27 11:02:47

任务调度

Unicode Framework 提供了灵活的任务调度系统,支持 Cron 表达式和便捷的调度方法。

调度器基础

创建调度器

use Unicode\Framework\Schedule\Scheduler;

$scheduler = new Scheduler();

// 注册任务 $scheduler->daily(function() { // 每天执行的任务 });

// 运行调度器 $scheduler->run();

调度方法

每分钟执行

$scheduler->everyMinute(function() {
    // 每分钟执行
    echo "Task executed at " . date('Y-m-d H:i:s') . "\n";
});

每小时执行

$scheduler->hourly(function() {
    // 每小时执行
    cleanupCache();
});

每天执行

$scheduler->daily(function() {
    // 每天执行
    generateDailyReport();
});

每天指定时间执行

$scheduler->dailyAt('14:30', function() {
    // 每天 14:30 执行
    sendDailyEmail();
});

每周执行

// 每周日执行
$scheduler->weekly(function() {
    generateWeeklyReport();
});

// 每周一执行 $scheduler->weekly(function() { sendWeeklyEmail(); }, day: 1);

每月执行

// 每月1号执行
$scheduler->monthly(function() {
    generateMonthlyReport();
});

// 每月指定日期执行 $scheduler->monthlyOn(15, function() { processMonthlyBilling(); });

使用 Cron 表达式

// 使用 Cron 表达式
$scheduler->cron('0 2   *', function() {
    // 每天凌晨2点执行
    backupDatabase();
});

// 每5分钟执行 $scheduler->cron('/5 *', function() { checkSystemStatus(); });

Cron 表达式

Cron 表达式格式

    *
│ │ │ │ │
│ │ │ │ └─── 星期几 (0-7, 0和7都表示周日)
│ │ │ └───── 月份 (1-12)
│ │ └─────── 日期 (1-31)
│ └───────── 小时 (0-23)
└─────────── 分钟 (0-59)

Cron 表达式示例

// 每分钟
$scheduler->cron('    *', $callback);

// 每小时的第0分钟 $scheduler->cron('0 ', $callback);

// 每天凌晨2点 $scheduler->cron('0 2 *', $callback);

// 每周一凌晨2点 $scheduler->cron('0 2 1', $callback);

// 每月1号凌晨2点 $scheduler->cron('0 2 1 ', $callback);

// 每5分钟 $scheduler->cron('/5 *', $callback);

// 工作日上午9点 $scheduler->cron('0 9 1-5', $callback);

任务定义

闭包任务

$scheduler->daily(function() {
    // 执行任务
    db('logs')->where('created_at', '<', date('Y-m-d', strtotime('-30 days')))->delete();
});

任务类

namespace App\Tasks;

use Unicode\Framework\Interfaces\ScheduledTaskInterface;

class CleanupOldLogs implements ScheduledTaskInterface { public function execute(): void { db('logs') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->delete(); } }

// 注册任务 $scheduler->daily(new CleanupOldLogs());

带描述的任务

$scheduler->daily(
    function() {
        generateReport();
    },
    description: '生成每日报告'
);

任务修饰符

限制执行环境

$scheduler->daily(function() {
    // 只在生产环境执行
})->environments('production');

// 多个环境 $scheduler->daily(function() { // 在生产和预发布环境执行 })->environments('production', 'staging');

限制执行时间

$scheduler->hourly(function() {
    // 只在工作时间内执行
})->between('09:00', '18:00');

// 排除时间段 $scheduler->hourly(function() { // 不在午休时间执行 })->unlessBetween('12:00', '13:00');

防止重叠执行

$scheduler->everyMinute(function() {
    // 如果上次执行未完成,跳过本次执行
})->withoutOverlapping();

运行调度器

命令行运行

<h1 id="运行调度器">运行调度器</h1>
php console schedule:run

<h1 id="查看计划任务">查看计划任务</h1> php console schedule:list

Cron 配置

在服务器上配置 Cron,每分钟执行一次:

<h1 id="编辑-crontab">编辑 crontab</h1>
crontab -e

<h1 id="添加以下行">添加以下行</h1> * cd /path/to/project && php console schedule:run >> /dev/null 2>&1

使用 Supervisor

<h1 id="etcsupervisorconfdschedulerconf">/etc/supervisor/conf.d/scheduler.conf</h1>
[program:scheduler]
command=php /path/to/console schedule:run
directory=/path/to/project
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/path/to/logs/scheduler.log

完整示例

定义多个任务

use Unicode\Framework\Schedule\Scheduler;

$scheduler = new Scheduler();

// 每分钟:检查系统状态 $scheduler->everyMinute(function() { checkSystemHealth(); }, '检查系统状态');

// 每小时:清理缓存 $scheduler->hourly(function() { cleanupCache(); }, '清理缓存');

// 每天凌晨2点:备份数据库 $scheduler->dailyAt('02:00', function() { backupDatabase(); }, '备份数据库');

// 每天上午9点:发送日报 $scheduler->dailyAt('09:00', function() { sendDailyReport(); }, '发送日报');

// 每周一:生成周报 $scheduler->weekly(function() { generateWeeklyReport(); }, day: 1, description: '生成周报');

// 每月1号:生成月报 $scheduler->monthlyOn(1, function() { generateMonthlyReport(); }, '生成月报');

// 运行调度器 $scheduler->run();

最佳实践

1. 任务组织

// ✅ 推荐:按功能组织任务
class ScheduleServiceProvider
{
    public function register(Scheduler $scheduler): void
    {
        $this->registerCleanupTasks($scheduler);
        $this->registerReportTasks($scheduler);
        $this->registerNotificationTasks($scheduler);
    }

private function registerCleanupTasks(Scheduler $scheduler): void { $scheduler->daily(function() { cleanupOldLogs(); }); } }

2. 错误处理

// ✅ 推荐:任务中处理错误
$scheduler->daily(function() {
    try {
        generateReport();
    } catch (\Exception $e) {
        Log::error('Scheduled task failed', [
            'task' => 'generateReport',
            'error' => $e->getMessage(),
        ]);
    }
});

3. 任务日志

// ✅ 推荐:记录任务执行日志
$scheduler->daily(function() {
    Log::info('Starting daily cleanup');

$deleted = cleanupOldData();

Log::info('Daily cleanup completed', [ 'deleted_count' => $deleted, ]); }, '每日清理任务');

4. 防止重叠

// ✅ 推荐:长时间运行的任务防止重叠
$scheduler->hourly(function() {
    processLargeDataset();
}, '处理大数据集')->withoutOverlapping();

5. 环境限制

// ✅ 推荐:根据环境限制任务
$scheduler->daily(function() {
    sendProductionEmail();
}, '发送生产邮件')->environments('production');

6. 时间限制

// ✅ 推荐:限制任务执行时间
$scheduler->hourly(function() {
    sendNotifications();
}, '发送通知')->between('09:00', '18:00');

常见问题

Q: 如何查看计划任务列表?

A: 使用 php console schedule:list 命令。

Q: 任务执行失败怎么办?

A: 在任务中添加错误处理,记录日志。

Q: 如何测试任务?

A: 手动运行任务或使用测试环境。

Q: Cron 表达式如何验证?

A: 使用在线 Cron 表达式验证工具。

Q: 如何监控任务执行?

A: 在任务中记录日志,使用监控工具查看日志。

相关文档