yii::$app->queue->push是任务入队入口,但需正确配置组件、定义job类、运行worker进程且环境一致,否则会静默失败;db驱动不支持delay()和priority(),表需迁移并建索引。

Yii::$app->queue->push 是把任务塞进队列的入口,但直接调用它不等于任务就能跑起来——缺配置、少 worker、没任务类,都会静默失败。
yii\queue\db\Queue 配置时 tableName 和 db 必须匹配实际环境
数据库队列最常用,但容易卡在表不存在或连接错库上。比如你配了 'db' => 'db',就得确认 config/main.php 里真有这个 db 组件;'tableName' => '{{%queue}}' 则要求运行过迁移:php yii queue/migrate,否则 push 不报错但数据写不进表。
- 表名带前缀(如
tbl_queue)时,别漏掉{{%}}占位符,否则建表和查表对不上 -
retryLimit设为-1虽然能无限重试,但失败任务会一直卡在reserved_at状态,得配合php yii queue/listen或定期清理 - 如果用 MySQL,建议给
queue表加INDEX (reserved_at, done_at),否则run命令查待执行任务会越来越慢
Job 类必须实现 yii\queue\JobInterface,且 execute() 参数不能改签名
很多人自定义 Job 类时加了额外参数,比如 execute($queue, $extra),这会导致反序列化后调用失败,错误信息是 Too few arguments —— 因为框架只传一个 $queue 实例进去。
- 所有业务数据必须通过 public 属性传入,如
public $userId; public $action; - 不要在
execute()里做exit或die,worker 进程会直接退出,后续任务全断 - 如果任务要访问 Yii 应用实例(比如发邮件),用
\Yii::$app没问题,但注意 console 环境下web组件不可用
php yii queue/run 启动 worker 前必须确认运行环境一致
Web 请求中 push 的任务,和 queue/run 执行的环境可能不同:一个是 web 入口,一个是 console 入口。常见坑是组件配置只写在 config/web.php 里,结果 queue/run 报错说找不到 queue 组件。
- 队列组件配置必须放在
config/console.php(或被它引入的公共配置文件中) - 命令行运行时默认加载
console配置,不是web配置,哪怕你在web中也能调用Yii::$app->queue - 如果要用
--verbose看日志,确保log组件在 console 配置里也启用了 file target,否则输出全丢
delay() 和 priority() 必须在 push 前链式调用,且仅部分驱动支持
Yii::$app->queue->delay(60)->push($job) 看起来很顺,但它只对 redis 和 amqp 驱动生效;db 驱动根本不识别 delay,任务会立刻进入可执行状态。
-
delay()底层依赖驱动是否提供延迟投递能力,db队列只能靠轮询 +pushed_at字段模拟,精度差、开销大 -
priority()在redis中有效,在db中完全被忽略 —— 因为数据库查询没加ORDER BY priority - 想精确控制延时,别依赖
delay(),改用定时任务(如 crontab 调php yii queue/run --count=1)或换 Redis 驱动
push,而是让整个链路在 Web 和 Console 两个上下文里行为一致、失败可追溯、积压可感知。尤其当任务涉及事务、缓存、用户 session 时,得主动剥离这些上下文依赖,而不是指望框架自动处理。











