Laravel 8.x Console Kernel调度Job不生效问题排查
Laravel 8 定时分发队列任务不生效问题
现有实现
队列任务代码
编写了SetQuizStatus队列任务,用于自动更新测验发布状态,代码如下:
<?php namespace App\Jobs; use Carbon\Carbon; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Modules\Quiz\Entities\Quiz; class SetQuizStatus implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $quiz; public function handle() { Quiz::where('publish_datetime', '>=', Carbon::now())->update([ 'status' => EnumHelper::get('quiz.status.published'), ]); } }
定时调度配置
在app/Console/Kernel.php中配置了每分钟触发一次该任务的调度规则:
protected function schedule(Schedule $schedule) { $schedule->command('backup:clean')->daily()->at('04:00'); $schedule->command('backup:run')->daily()->at('05:00'); $schedule->job(new SetQuizStatus)->everyMinute(); }
问题表现
- 预期效果:当测验的
publish_datetime到达设定时间时,自动更新对应测验状态为已发布 - 执行
php artisan schedule:run验证时,php artisan schedule:list可以正常展示该调度条目,但任务没有实际执行效果 - 当前
.env中QUEUE_CONNECTION配置值为database
遗漏步骤与问题修正
- 核心遗漏:使用
database队列驱动时,定时任务到点只会把Job推送到jobs队列表中,不会自动执行任务,必须启动队列消费进程才会真正运行Job逻辑:- 如果还没生成队列表,先执行迁移命令创建表结构:
php artisan queue:table php artisan migrate - 启动队列工作进程常驻消费任务:
php artisan queue:work
queue:work进程,保证异常退出后自动重启,代码更新后需要重启进程才能加载新逻辑。 - 如果还没生成队列表,先执行迁移命令创建表结构:
- 额外逻辑bug:当前任务里的查询条件写反了,
>=当前时间会把还没到发布时间的测验标记为已发布,正确的查询条件应该是筛选发布时间小于等于当前时间、且还没标记为已发布的测验:Quiz::where('publish_datetime', '<=', Carbon::now()) ->where('status', '<>', EnumHelper::get('quiz.status.published')) ->update([ 'status' => EnumHelper::get('quiz.status.published'), ]); - 可选简化方案:如果不想维护常驻队列进程,可以在调度时指定使用
sync同步驱动,任务触发时会直接执行,不需要队列进程:$schedule->job(new SetQuizStatus, 'sync')->everyMinute();
内容的提问来源于stack exchange,提问作者Cascavel
相关产品推荐
相关产品推荐

