laravel框架怎么使用队列

1203  ·  2019-08-18 22:58:55  ·  网站建设技术  ·  网站开发

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 App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use App\Models\Topic;
use App\Handlers\SlugTranslateHandler;

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 App\Observers;

use App\Models\Topic;
use App\Jobs\TranslateSlug;

// 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

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

本文地址:laravel框架怎么使用队列

在线留言

免费获取解决方案!

Write here

我们提供的产品解决方案 >>

百度SEO

01 AI万词霸屏

搜狗SEO

02 关键词优化(SEO)

SEO诊断

03 免费SEO诊断

SEO培训

04 SEO营销推广

SEO顾问

05 SEO方案定制

网站降权

06 网站降权恢复

百度SEO

07 整站优化

搜狗SEO

08 微信小程序

SEO诊断

09 微商城开发

SEO培训

10 网站竞价托管

SEO顾问

11 社区团购系统

网站降权

12 积分管理系统

为您推荐