Laravel9队列同步执行致页面阻塞、jobs表为空问题咨询
Laravel 9 队列投递后同步阻塞、不写入jobs表问题排查
问题场景
尝试投递队列任务实现异步执行,相关代码如下:
控制器代码
public function play($id, Request $request) { ProcessResult::dispatch($id); dd('done'); }
任务类代码
public function handle() { sleep(25); // 业务逻辑省略 }
异常表现
- 数据库
jobs表为空,无任何任务写入记录 - 浏览器页面持续加载阻塞,直到任务执行完成才返回响应
dd('done')语句需等待任务执行完毕才会输出结果
当前运行环境为本地localhost,队列驱动已配置为database,框架版本为Laravel 9。
问题根因
该问题属于对Laravel队列运行逻辑的理解偏差,并非配置写入错误,核心触发原因如下:
- Laravel队列默认连接优先级为:任务类手动指定的
$connection属性 >.env中QUEUE_CONNECTION配置 > 配置文件默认值。绝大多数本地开发环境的初始.env配置中,QUEUE_CONNECTION默认值为sync(同步驱动),如果没有手动修改该值,哪怕你认为自己配置了database驱动,实际仍然会走同步执行逻辑。 sync同步驱动的设计逻辑就是不做任何任务持久化,不会往jobs表写入数据,而是在当前请求的生命周期内直接执行任务的handle方法,完全匹配所有异常现象:- 无jobs表记录:同步驱动不需要持久化任务,自然不会执行表写入操作
- 页面阻塞:任务在请求进程内同步执行,
sleep(25)会直接阻塞请求25秒 dd延迟输出:dispatch方法调用时就会同步执行完所有任务逻辑,才会继续执行后续代码
- 特殊排查点:如果确认已经修改了
.env中的队列连接,大概率是之前执行过config:cache命令缓存了旧配置,导致新配置未生效;另外需要检查ProcessResult任务类中是否手动声明了protected $connection = 'sync',该属性会覆盖全局配置强制走同步驱动。
修复步骤
- 修改项目根目录
.env文件中的队列连接配置:QUEUE_CONNECTION=database - 清除配置缓存,让新配置生效:
php artisan config:clear - 注意:使用
database等异步队列驱动时,投递任务的动作只会把任务写入jobs表,不会自动执行任务,需要单独启动队列消费进程才能处理任务,启动命令如下:php artisan queue:work
修复完成后重新触发请求,任务会先写入jobs表,请求会立刻执行到dd('done')返回结果,不会出现阻塞,待队列进程启动后,存储在表中的任务才会被依次消费执行。
内容的提问来源于stack exchange,提问作者Shoshin
相关产品推荐
相关产品推荐

