确认phpredis扩展已启用且版本兼容:运行php -m | grep redis有输出;Laravel 9.x要求≥5.3.7,需在database.php中显式设'client' => 'phpredis',三处配置(.env/database.php/queue.php)主机、端口等必须严格一致。

确认 phpredis 扩展已启用且版本兼容
运行 php -m | grep redis,有输出才代表扩展加载成功;若无,需检查 php.ini 是否含 extension=redis 并重启 PHP-FPM。Laravel 9.x 要求 phpredis ≥ 5.3.7(对应 Redis 7+ 协议),低于该版本可能在 retry_after 或连接复用时出现静默失败。
特别注意:config/database.php 中 'client' => 'phpredis' 必须显式写出,不能留空或写成 'predis'——否则 queue:work 启动时直接抛出 ClassNotFound 错误,且 Laravel 不会提示具体缺哪个类。
三处配置必须严格对齐:.env / database.php / queue.php
这三处任何一项主机、端口、密码、database 索引或 connection 键名不一致,任务就会 dispatch() 成功但永不被消费,日志里也查不到错误。
-
.env中强制设四行:QUEUE_CONNECTION=redis、REDIS_HOST=10.0.0.5、REDIS_PORT=6380、REDIS_PASSWORD=null(无密码必须写null,空字符串会导致 AUTH 失败) -
config/database.php的redis.default块中,确保'database' => 1(避免和缓存共用 db0),并显式加'timeout' => 5和'read_write_timeout' => -1 -
config/queue.php的redis驱动里,'connection' => 'default'必须与database.php中的键名完全一致;'queue' => 'prod:notifications'建议带命名空间前缀,防止开发队列混入生产数据
任务类必须实现 ShouldQueue,且不能依赖未序列化对象
仅 implements ShouldQueue 不够,还要确认构造函数参数可被 phpredis 正确序列化。例如传入 Illuminate\Http\Request 或闭包会直接导致任务卡在 Redis 里无法反序列化——queue:work 日志只显示 Processing 然后静默退出。
立即学习“PHP免费学习笔记(深入)”;
推荐做法:
- 在
handle()方法内重新 resolve 服务,而非在__construct()中注入 - 敏感数据(如 token、临时文件路径)不要直接塞进构造参数,改用 ID + 查询方式延迟加载
- 执行
php artisan config:clear后再启动队列,否则缓存配置可能掩盖database.php中的修改
启动与守护:别用 queue:listen,必须用 Supervisor 管理 queue:work
php artisan queue:listen 在 Laravel 9.x 已废弃,且它不会重载代码变更,容易因类加载失效导致任务失败后无限重试。
生产环境唯一可靠方式是:
- 用
php artisan queue:work --queue=prod:notifications --sleep=3 --tries=3 --timeout=60启动单个 worker - 配合 Supervisor 守护,配置中必须设
autorestart=true和stopwaitsecs=30,否则 SIGTERM 杀进程时正在执行的任务会被强制中断 - Redis 8.2.3 已修复 CVE-2025-62507(RCE 漏洞),若仍在用旧版,升级前务必禁用
eval相关命令(Laravel 队列本身不依赖 eval,但自定义 Lua 脚本可能触发)
最容易被忽略的是 read_write_timeout 设为 -1 ——很多线上任务卡住不是因为 Redis 挂了,而是网络抖动后 phpredis 在读响应时无限等待,worker 进程就此僵死,Supervisor 也检测不到异常。



















