Skip to content

任务调度

租户命令继承 Modules\Tenancy\Commands\TenancyCommand。每次执行会遍历状态正常且未到期的可用租户,并在每个租户上下文中调用一次 handle()

创建租户命令

命令名称和 Artisan 签名都应明确提供:

shell
php artisan catch:tenant:command Cleanup --command=tenant:cleanup

生成文件为 app/Console/Commands/Cleanup.php,命名空间是 App\Console\Commands

php
<?php

namespace App\Console\Commands;

use Modules\Tenancy\Commands\TenancyCommand;

class Cleanup extends TenancyCommand
{
    protected $signature = 'tenant:cleanup';

    protected $description = '清理租户过期数据';

    public function handle(): int
    {
        $this->info('正在处理租户:'.tenant('id'));

        // 当前数据库、缓存、文件系统和日志均属于当前租户。

        return self::SUCCESS;
    }
}

停用或已到期租户不会进入本次遍历。命令中的查询直接作用于当前租户数据库。

注册 Laravel Scheduler

routes/console.php 注册调度任务:

php
<?php

use Illuminate\Support\Facades\Schedule;

Schedule::command('tenant:cleanup')
    ->dailyAt('02:00')
    ->title('tenant:cleanup')
    ->graceTimeInMinutes(30)
    ->storeOutputInDb();

租户包为 Laravel 调度事件增加四个监控宏:

作用
title(string $title)设置监控任务名称;名称用于同步和匹配执行日志
graceTimeInMinutes(int $minutes)设置允许完成的宽限时间,默认 5 分钟
storeOutputInDb(bool $enabled = true)捕获命令输出并保存到调度日志
doNotMonitor(bool $disabled = true)排除无需进入调度监控的任务

任务名称必须保持唯一和稳定。当前页面的“立即执行”会把该名称作为 Artisan 命令调用,因此命令任务的 title() 应与命令签名保持一致;未调用 title() 时会使用完整命令作为默认名称。

开发环境可以直接运行:

shell
php artisan schedule:work

生产环境每分钟调用 Laravel Scheduler:

text
* * * * * cd /var/www/catchadmin && php artisan schedule:run >> /dev/null 2>&1

调度监控页面

多租户 → 调度监控 页面使用中央数据库的 schedule_tasksschedule_task_log_items 表:

  • 同步任务:读取当前 Laravel Scheduler 中已注册且允许监控的任务,更新监控列表。
  • 执行任务:立即执行列表中的 Artisan 命令。
  • 执行日志:查看完成、失败、跳过、运行时间、退出码和已捕获输出。
  • 清理日志:删除指定任务的历史执行日志。

中央管理员权限由 TenancyMenusSeeder 定义:

页面操作权限标识
查看列表及任务日志scheduleTask@index
同步任务scheduleTask@sync
立即执行scheduleTask@run
清理日志scheduleTask@clearLog

部署新任务或修改 Cron 表达式后,在页面点击“同步任务”。Scheduler 正常运行后,任务的开始、完成、失败和跳过事件会自动写入中央调度日志。