网站建设咨询
ECS云服务器,3年付仅3折,17元/月起

【萍乡网站开发】laravel框架怎么使用队列

1. 配置队列

队列的配置信息储存于 config/queue.php 文件中,在这个文件中你会发现框架所支持的队列驱动的配置连接示例。这些驱动包括:数据库,Beanstalkd,Amazon SQS,Redis,和一个同步(本地使用)的驱动。还有一个名为 null 的驱动表明不使用队列任务。

本项目中,我们将使用 Redis 来作为我们的队列驱动器,先使用 Composer 安装依赖:

composer require "predis/predis:~1.1"

修改环境变量 QUEUE_DRIVER 的值为 redis:

.env

.
.
.
QUEUE_CONNECTION=redis
.
.
.

失败任务

有时候队列中的任务会失败。Laravel 内置了一个方便的方式来指定任务重试的最大次数。当任务超出这个重试次数后,它就会被插入到 failed_jobs 数据表里面。我们可以使用 queue:failed-table 命令来创建 failed_jobs 表的迁移文件:

 php artisan queue:failed-table

会新建 database/migrations/{timestamp}_create_failed_jobs_table.php 文件:
接着使用 migrate Artisan 命令生成 failed_jobs 表:

$ php artisan migrate

  1. 生成任务类

使用以下 Artisan 命令来生成一个新的队列任务:

$ php artisan make:job TranslateSlug
该命令会在 app/Jobs 目录下生成一个新的类:

app/Jobs/TranslateSlug.php

<?php

namespace AppJobs;

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

use AppModelsTopic;
use AppHandlersSlugTranslateHandler;

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(SlugTranslateHandler::class)->translate($this->topic->title);

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

}
该类实现了 IlluminateContractsQueueShouldQueue 接口,该接口表明 Laravel 应该将该任务添加到后台的任务队列中,而不是同步执行。

引入了 SerializesModels trait,Eloquent 模型会被优雅的序列化和反序列化。队列任务构造器中接收了 Eloquent 模型,将会只序列化模型的 ID。这样子在任务执行时,队列系统会从数据库中自动的根据 ID 检索出模型实例。这样可以避免序列化完整的模型可能在队列中出现的问题。

handle 方法会在队列任务执行时被调用。值得注意的是,我们可以在任务的 handle 方法中可以使用类型提示来进行依赖的注入。Laravel 的服务容器会自动的将这些依赖注入进去,与控制器方法类似。

还有一点需要注意,我们将会在模型监控器中分发任务,任务中要避免使用 Eloquent 模型接口调用,如:create(), update(), save() 等操作。否则会陷入调用死循环 —— 模型监控器分发任务,任务触发模型监控器,模型监控器再次分发任务,任务再次触发模型监控器.... 死循环。在这种情况下,使用 DB 类直接对数据库进行操作即可。

  1. 任务分发

接下来我们要修改 Topic 模型监控器,将 Slug 翻译的调用修改为队列执行的方式:

app/Observers/TopicObserver.php

<?php

namespace AppObservers;

use AppModelsTopic;
use AppJobsTranslateSlug;

// creating, created, updating, updated, saving,
// saved, deleting, deleted, restoring, restored

class TopicObserver
{

public function saving(Topic $topic)
{
    // XSS 过滤
    $topic->body = clean($topic->body, 'user_topic_body');

    // 生成话题摘录
    $topic->excerpt = make_excerpt($topic->body);

    // 如 slug 字段无内容,即使用翻译器对 title 进行翻译
    if ( ! $topic->slug) {

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

}

  1. 开始测试

开始之前,我们需要在命令行启动队列系统,队列在启动完成后会进入监听状态:

php artisan queue:listen
浏览器打开话题发布页面,填写测试内容:

长沙网站建设|开发|制作|技术-吾爱阅读博客
请先登录后发表评论
  • latest comments
  • 总共0条评论