You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel基于模型关联删除队列任务及相关管理需求咨询

Laravel Redis队列任务管理方案(对应你的三个需求)

1. 删除特定模型ID关联的待处理任务

Redis驱动的队列里,待处理任务分两种:普通队列(queues:{队列名})和延迟队列(queues:{队列名}:delayed)。要删除指定模型ID的任务,需先给邮件任务打上标识,再扫描Redis队列匹配删除。

第一步:给邮件类添加模型ID属性

确保你的Mailable类携带模型ID,这样序列化后能被识别:

namespace App\Mail;

use Illuminate\Mail\Mailable;

class ReservationMail extends Mailable
{
    public $modelId;

    public function __construct(int $modelId)
    {
        $this->modelId = $modelId;
    }

    public function build()
    {
        return $this->view('emails.reservation');
    }
}

第二步:扫描并删除匹配任务

写一个工具方法(可封装成Artisan命令方便调用):

use Illuminate\Support\Facades\Redis;
use App\Models\Reservation;

function purgeTasksForModel(int $modelId, string $queue = 'default')
{
    // 处理普通待处理队列
    $queueKey = "queues:$queue";
    $tasks = Redis::lrange($queueKey, 0, -1);
    
    foreach ($tasks as $taskJson) {
        $payload = json_decode($taskJson, true);
        if ($this->isMatchingTask($payload, $modelId)) {
            Redis::lrem($queueKey, 1, $taskJson);
        }
    }

    // 处理延迟队列
    $delayedKey = "queues:$queue:delayed";
    $delayedTasks = Redis::zrange($delayedKey, 0, -1, true);
    
    foreach ($delayedTasks as $taskJson => $timestamp) {
        $payload = json_decode($taskJson, true);
        if ($this->isMatchingTask($payload, $modelId)) {
            Redis::zrem($delayedKey, $taskJson);
        }
    }

    // 同步删除数据库关联记录(对应手动删除任务的场景)
    Reservation::where('id', $modelId)->delete();
}

// 辅助方法:判断任务是否匹配目标模型ID
private function isMatchingTask(array $payload, int $modelId): bool
{
    if (!isset($payload['data']['commandName'], $payload['data']['command'])) {
        return false;
    }

    // 只处理邮件队列任务
    if ($payload['data']['commandName'] !== \Illuminate\Mail\SendQueuedMailable::class) {
        return false;
    }

    // 反序列化任务,提取模型ID(仅处理自身任务,避免安全风险)
    $command = unserialize($payload['data']['command']);
    return $command->mailable->modelId === $modelId;
}

2. 记录任务实际执行时间戳

利用Laravel的队列事件监听,在任务执行完成后更新数据库记录。

注册事件监听器

在App\Providers\EventServiceProvider的$listen数组里添加:

protected $listen = [
    \Illuminate\Queue\Events\JobProcessed::class => [
        \App\Listeners\LogJobExecution::class,
    ],
];

创建监听器类

生成监听器:php artisan make:listener LogJobExecution,然后修改内容:

namespace App\Listeners;

use Illuminate\Queue\Events\JobProcessed;
use App\Models\Reservation;

class LogJobExecution
{
    public function handle(JobProcessed $event)
    {
        $payload = $event->job->payload();
        
        // 过滤非邮件任务
        if (!isset($payload['data']['commandName']) || $payload['data']['commandName'] !== \Illuminate\Mail\SendQueuedMailable::class) {
            return;
        }

        // 提取模型ID并更新执行时间
        $command = unserialize($payload['data']['command']);
        Reservation::where('id', $command->mailable->modelId)
            ->update(['executed_at' => now()]);
    }
}

3. 邮件未发送时删除关联记录

邮件未发送的场景分两种:任务执行失败(重试耗尽后)、手动删除待处理任务。

处理任务失败场景

监听JobFailed事件,在EventServiceProvider里添加:

protected $listen = [
    // 之前的JobProcessed
    \Illuminate\Queue\Events\JobFailed::class => [
        \App\Listeners\CleanupFailedJob::class,
    ],
];

生成监听器:php artisan make:listener CleanupFailedJob,修改内容:

namespace App\Listeners;

use Illuminate\Queue\Events\JobFailed;
use App\Models\Reservation;

class CleanupFailedJob
{
    public function handle(JobFailed $event)
    {
        $payload = $event->job->payload();
        
        if (!isset($payload['data']['commandName']) || $payload['data']['commandName'] !== \Illuminate\Mail\SendQueuedMailable::class) {
            return;
        }

        $command = unserialize($payload['data']['command']);
        Reservation::where('id', $command->mailable->modelId)->delete();
    }
}

处理手动删除任务场景

在需求1的purgeTasksForModel方法里,已同步删除数据库关联记录,无需额外操作。

注意事项

  • 测试时可通过Redis::keys('queues:*')查看所有队列键,再用Redis::lrange('queues:default', 0, -1)查看任务内容,确认匹配规则是否正确。
  • 若使用多队列,需遍历所有队列键(通过Redis::keys('queues:*')过滤),或指定目标队列名称。
  • 反序列化任务时,确保Mailable类的属性未修改,否则会触发序列化异常。

内容的提问来源于stack exchange,提问作者Cat Named Dog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:27:24