Laravel 6.18使用dispatchAfterResponse未释放前端请求该如何解决?
问题根因
你遇到这个问题的核心原因是默认使用了sync同步队列驱动:sync驱动会把所有任务放在当前请求进程内执行,哪怕调用了dispatchAfterResponse方法,任务执行也会阻塞响应的完整发送,你在浏览器看到的200只是响应头状态,响应体还没有被服务器推送给客户端,所以前端请求会一直pending直到超时。
解决步骤
1. 切换非同步队列驱动
首先修改项目根目录下的.env配置文件,将队列驱动改为非同步类型,最便于测试的是数据库驱动:
QUEUE_CONNECTION=database
如果是首次使用数据库队列,执行以下命令生成队列表并迁移:
php artisan queue:table php artisan migrate
2. 调整任务调度代码
原来的调度代码不需要改,两种写法在异步队列场景下都可以生效:
EmailJob::dispatchAfterResponse(); return response()->json($obj, 200);
3. 启动队列消费者进程
异步任务需要独立的进程消费执行,在命令行执行以下命令启动队列监听:
php artisan queue:work
测试阶段保持这个终端运行即可,生产环境建议用Supervisor等工具守护队列进程,避免进程意外退出导致任务丢失。
可选:无需队列的临时测试方案
如果你只是本地临时测试不想配置队列,需要确认你的Web服务器(Nginx+PHP-FPM/Apache)开启了fastcgi_finish_request支持,在返回响应前手动刷出输出缓冲即可:
ob_end_flush(); flush(); EmailJob::dispatchAfterResponse(); return response()->json($obj, 200);
该方案仅适合测试使用,生产环境仍推荐使用异步队列保证任务可靠性。
内容的提问来源于stack exchange,提问作者uneasy
相关产品推荐
相关产品推荐

