queue_connection=redis必须与redis实际连接完全一致,否则任务静默积压;需确保.env、config/database.php、config/queue.php三处配置联动,扩展已安装,supervisor显式传递环境变量,且任务类正确实现shouldqueue接口并避免序列化问题。

QUEUE_CONNECTION=redis 配置必须和 Redis 实际连接一致
任务 dispatch 后没反应,八成是 QUEUE_CONNECTION 和真实 Redis 连接对不上。比如 .env 写了 QUEUE_CONNECTION=redis,但 config/database.php 里 redis.default 的 host 指向了错的地址,或者 REDIS_PASSWORD 没配对——结果任务静默积压,queue:work 进程连都连不上。
-
composer require predis/predis必须执行,否则 Laravel 默认找不到 Redis 客户端 -
config/queue.php中redis.connection值(如'default')要和config/database.php里redis数组的键名完全一致 -
REDIS_CLIENT=predis建议显式写在.env中,避免因环境差异 fallback 到未启用的phpredis - 用
redis-cli -h $REDIS_HOST -p $REDIS_PORT ping手动验证 Redis 是否可达,别只信配置文件
php artisan queue:work redis 要匹配驱动,不能混用
运行监听命令时,queue:work 后面跟的驱动名必须和 QUEUE_CONNECTION 值一致,否则会连错后端、读不到任务。例如 QUEUE_CONNECTION=redis,就必须用 php artisan queue:work redis,而不是 php artisan queue:work database 或直接不带参数。
- 开发调试时可加
--verbose:运行php artisan queue:work redis --verbose,看控制台是否输出Processing或Failed日志 - 终端关闭后进程就停,生产环境绝不能靠手动运行;必须用 Supervisor 管理,且
command中明确指定queue:work redis -
queue:listen已被 Laravel 弃用,别再用;它每次启动新进程,开销大、不可控 - 若用 Horizon,启动的是
php artisan horizon,它内部自动调用queue:work redis,无需额外起 worker
任务类必须实现 ShouldQueue,且构造函数只传 ID
没实现 ShouldQueue 接口的任务,哪怕写了 ::dispatch(),也会被 Laravel 当作普通 PHP 对象同步执行,根本不会进 Redis 队列。
- 类声明必须包含
implements ShouldQueue,不能只写use Queueable - 构造函数里别传 Eloquent 模型实例,而应传
$user->id;在handle()里用User::find($this->userId)查库 -
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;这四个 trait 缺一不可,尤其是SerializesModels,否则模型序列化失败会导致任务卡住 - 检查
storage/logs/laravel.log,搜索Serialization of 'Closure'或unserialize(): Error at offset,这是典型的构造函数传了闭包或资源句柄
Redis 队列里有任务但不消费?先查连接与权限
用 LRANGE queues:default 0 -1 能看到任务入队,但 queue:work 不处理,说明问题出在消费者端连接或权限上,不是任务没发出去。
- 确认 Redis 数据库编号(
database)没超范围:config/database.php中redis.default.database默认是0,如果改过,config/queue.php的redis驱动也要同步 -
retry_after设置太短(如10秒)会导致长任务被重复执行;建议设为任务最大耗时 + 10 秒,比如邮件发送设90 - Redis 密码含特殊字符(如
@、/)时,REDIS_URL格式需 URL 编码,否则predis解析失败 - Supervisor 配置中
environment=QUEUE_CONNECTION="redis"必须显式声明,否则子进程读不到.env里的值











