主题
任务调度
租户命令继承 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_tasks 和 schedule_task_log_items 表:
- 同步任务:读取当前 Laravel Scheduler 中已注册且允许监控的任务,更新监控列表。
- 执行任务:立即执行列表中的 Artisan 命令。
- 执行日志:查看完成、失败、跳过、运行时间、退出码和已捕获输出。
- 清理日志:删除指定任务的历史执行日志。
中央管理员权限由 TenancyMenusSeeder 定义:
| 页面操作 | 权限标识 |
|---|---|
| 查看列表及任务日志 | scheduleTask@index |
| 同步任务 | scheduleTask@sync |
| 立即执行 | scheduleTask@run |
| 清理日志 | scheduleTask@clearLog |
部署新任务或修改 Cron 表达式后,在页面点击“同步任务”。Scheduler 正常运行后,任务的开始、完成、失败和跳过事件会自动写入中央调度日志。