Laravel队列简单使用

2022-09-08 19:13:10 浏览数 (1)

消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦。所以主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。同时由于使用了消息队列,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦和。

配置队列

安装扩展包

代码语言:javascript复制
composer require "predis/predis:~1.0"

队列的配置信息存放在config/queue.php 在.env中修改配置驱动 QUEUE_DRIVER=redis 使用redis驱动 REDIS_CLIENT=predis 使用predis

生成队列需要的数据表

有时候队列会执行失败,这张表用于存放失败信息

代码语言:javascript复制
php artisan queue:failed-table
php artisan migrate

生成任务类

生成的文件存放在 appJobs

代码语言:javascript复制
php artisan make:jon QueueName

该文件有两个方法 _construct构造方法 注入模型 handler 任务的逻辑

代码语言:javascript复制
<?php

namespace AppJobs;

use IlluminateBusQueueable;
use IlluminateQueueSerializesModels;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchable;

use AppModelsTopic;
use AppHandlersTranslateHandler;

class TranslateSlug implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $topic;

    public function __construct(Topic $topic)
    {
        // 队列任务构造器中接收了 Eloquent 模型,将会只序列化模型的 ID
        $this->topic = $topic;
    }

    public function handle()
    {
        // 请求百度 API 接口进行翻译
        $slug = app(AppHandlersTranslateHandler::class)->translate($this->topic->title);

        // 为了避免模型监控器死循环调用,我们使用 DB 类直接对数据库进行操作
        DB::table('topics')->where('id', $this->topic->id)->update(['slug' => $slug]);
    }
}

注意

若任务涉及到了数据库的读写,需要注意 数据库的读写直接使用 DB 类,而不是使用 ORM 因为一般我们会在模型监听器中分发队列任务,此时,会形成一个死循环 通过 ORM 写数据库,触发 ORM 监听器 -> 分发队列任务 -> 任务中使用了 ORM 写数据库 -> 通过 ORM 写数据库,触发 ORM 监听器 -> ....

分发任务

调用 dispatch(new QueueName($model)) 将任务放在默认的队列上

代码语言:javascript复制
 public function saved(Topic $topic)
    {
        // 如 slug 字段无内容,即使用翻译器对 title 进行翻译
        if ( ! $topic->slug) {

            // 推送任务到队列
            dispatch(new TranslateSlug($topic));
        }
    }

队列监控

1.通过命令监控

代码语言:javascript复制
php artisan queue:listen

2.有图形界面的监控 Horizon 安装Horizon

代码语言:javascript复制
composer require "laravel/horizon:~1.0"

生成配置

代码语言:javascript复制
php artisan vendor:publish --provider="LaravelHorizonHorizonServiceProvider"

接下来输入 http://项目名称/horizon即可进入界面

输入命令监控队列

代码语言:javascript复制
php artisan horizon

0 人点赞