Skip to content

队列 Queue

支持同步(Sync)和 Redis 驱动。

配置

创建 config/queue.php

php
return [
    'default' => 'sync',
    'connections' => [
        'sync' => [
            'type' => 'sync',
        ],
        'redis' => [
            'type'     => 'redis',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'select'   => 0,
            'queue'    => 'default',
        ],
    ],
];

定义任务

php
// app/job/SendEmail.php
namespace App\job;

use Lychee\queue\Job;

class SendEmail extends Job
{
    public function __construct(
        protected string $email,
        protected string $content,
    ) {}

    public function handle(): void
    {
        // 发送邮件逻辑
    }
}

推送任务

php
queue(SendEmail::class, ['email' => 'a@b.com', 'content' => 'hi']);

// 指定队列
queue(SendEmail::class, $data, 'emails');

延迟任务

通过链式调用 delay() 设置延迟秒数,无需额外函数:

php
// 60 秒后执行
queue(SendEmail::class, ['email' => 'a@b.com'])->delay(60);

// 7 天后执行(使用表达式更清晰)
queue(CleanupJob::class)->delay(86400 * 7);

// 指定队列
queue(SendEmail::class, $data, 'emails')->delay(300);

queue() 返回一个 PendingDispatch 对象,调用 delay() 后在对象销毁时自动分发。

实现原理(Redis 驱动)

Redis 连接器使用三个数据结构协作:

  • 主队列 {queue}:List,存放立即可执行的任务
  • 延迟队列 {queue}:delayed:Sorted Set,score 为任务可执行的时间戳
  • 预留队列 {queue}:reserved:Sorted Set,存放正在执行的任务,用于超时重试

每次 pop() 取任务前,会调用 migrate():delayed 中已到期(score ≤ time())的任务移回主队列。

Sync 驱动

Sync 连接器在 delay() 大于 0 时会调用 sleep() 阻塞等待,然后立即执行任务。这是有意为之——Sync 定位为开发/测试环境,保证延迟语义与 Redis 驱动一致。生产环境请使用 Redis 驱动。

消费队列

bash
php lee queue:work --connection=redis --queue=default --tries=3

Released under the MIT License.