ThinkPHP用think-queue搭Redis队列必须对齐关键配置:安装composer require topthink/think-queue;TP6+读config/queue.php,TP8优先读config/extra/queue.php;select须为整数、password显式写''、retry_after>任务最长耗时、expire<retry_after;任务类namespace须为app\job且含fire(Job $job, $data)方法;监听需加--verbose验证,并用supervisor守护。

ThinkPHP 用 think-queue 搭 Redis 队列,不是“能跑就行”,而是必须对齐几个关键配置点,否则任务会卡住、重复执行、或根本进不了队列。
think-queue 安装与基础配置文件位置
安装命令固定为:composer require topthink/think-queue。安装后不要手动新建 config/queue.php —— ThinkPHP 6+ 默认从 config/queue.php 加载,但 TP8 实际优先读取 config/extra/queue.php(若存在)。你得确认自己改的是被加载的那个文件。
常见错误现象:改了 config/queue.php 却没生效,其实是框架在找 config/extra/queue.php;或者压根没创建该文件,导致使用默认的空配置,connector 为空,Queue::push() 直接静默失败。
- 检查是否已生成
config/extra/queue.php,没有就手动创建 - 确保文件返回的是数组,且顶层键包含
'default'和'connections' - TP8 中推荐用
Env::get()读取环境变量,比如'host' => Env::get('redis.host', '127.0.0.1'),避免硬编码
Redis 驱动配置里最容易错的四个参数
select、retry_after、expire、password 这四个值一旦设错,轻则任务不触发,重则任务无限重试或堆积。
立即学习“PHP免费学习笔记(深入)”;
典型错误:
-
'select' => "1"—— 字符串 1 不合法,必须是整数1,否则连接报错ERR invalid DB index -
'password' => null或直接省略 —— 密码为空时必须显式写'',否则底层连接会传null,Redis 拒绝认证 -
'retry_after' => 30但实际任务要跑 45 秒 —— 30 秒一到,队列认为任务失败并重新入队,造成重复执行 -
'expire' => 0—— 任务没超时控制,一旦消费者崩溃,任务就永远卡在队列里变成僵尸
建议值:
-
select:1–15(避开 0 号 DB,防止和缓存冲突) -
retry_after:设为最长任务耗时 × 1.3,比如预估 60 秒,就填78 -
expire:比retry_after小 10–20 秒,比如60 -
password:明确写''或真实密码字符串
任务类 fire() 方法为什么没执行?
不是所有命名空间都能被自动识别。ThinkPHP 要求任务类必须满足两个条件:namespace 必须以 app\job 开头,且类中必须有 fire(Job $job, $data) 方法(注意参数类型提示不能少)。
常见问题:
- 类放在
app/common/job下,namespace app\common\job——Queue::push()找不到类,报Class not found - 方法名写成
handle()或execute()—— 框架只认fire(),不会调用 - 没引入
use think\queue\Job;,导致$job参数类型校验失败,静默跳过 -
$data是数组但没做json_encode兼容处理,遇到对象或资源时报序列化异常
最简验证写法:
namespace app\job;
use think\queue\Job;
use think\facade\Log;
class SendEmail
{
public function fire(Job $job, $data)
{
Log::info('SendEmail fired with:', $data);
// 处理逻辑...
$job->delete(); // 记得删任务,否则会重试
}
}
监听进程启动后没反应?检查这三件事
php think queue:listen 启动后光标停住、无日志、无输出,不代表它挂了,但也不代表它在工作 —— 很可能连 Redis 都没连上。
- 先运行
php think queue:failed,看是否有失败记录;如果有,说明至少连上了 Redis 并尝试消费过 - 用
redis-cli手动查队列长度:llen think_queue_default(队列名来自配置里的queue值),确认任务确实进去了 - 加
--verbose参数启动监听:php think queue:listen --verbose,能看到连接、取任务、执行各阶段日志
真正上线必须用 supervisor 或 systemd 守护,别信 nohup php think queue:listen & —— PHP 进程遇到 SIGPIPE 或 OOM 会被系统干掉,没人重启它。
Redis 配置项里那个 persistent => true 看似可选,但在高并发下漏掉它,会导致每秒建立大量短连接,Redis 连接数暴涨甚至拒绝服务 —— 这个细节,上线前不压测根本发现不了。



















