Bootstrap

laravel 任务队列_Laravel 队列系统实现及使用教程

Laravel 队列系统实现及使用教程

由 学院君 创建于2年前, 最后更新于 9个月前

版本号 #2

48088 views

10 likes

0 collects

235058e845d8ee60b394002c3aa11cef.png

简介

注:Laravel 现在提供了基于 Redis 的,拥有美观的后台和配置系统的 Horizon 队列扩展包,完整信息参考 Horizon文档。

Laravel 队列为不同的后台队列服务提供了统一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于关系型数据库的队列。队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短 Web 请求和响应的时间。

队列配置文件存放在 config/queue.php。每一种队列驱动的配置都可以在该文件中找到,包括数据库、Beanstalkd、Amazon SQS、Redis以及同步(本地使用)驱动。其中还包含了一个 null 队列驱动用于那些放弃队列的任务。

连接 Vs. 队列

在开始使用 Laravel 队列以前,了解“连接”和“队列”的关系非常重要。在配置文件 config/queue.php 有一个 connections 配置项。该配置项定义了后台队列服务的特定连接,如 Amazon SQS, Beanstalk, 或 Redis。每种队列连接都可以有很多队列,可以想象在银行办理现金业务的各个窗口队列。

请注意 queue 配置文件中的每个连接配置示例都有一个 queue 属性。当新的队列任务被添加到指定的连接时,该配置项的值就是默认监听的队列(名称)。换种说法,如果你没有指派特别的队列名称,那么 queue 的值,也是该任务默认添加到的队列(名称):

// 以下的任务将被委派到默认队列...

dispatch(new Job);

// 以下任务将被委派到 "emails" 队列...

dispatch((new Job)->onQueue('emails'));

有些应用并不需要将任务分配到多个队列,单个队列已经非常适用。但是,应用的任务有优先级差异或者类别差异的时候,推送任务到多个队列将是更好地选择,因为 Laravel 的队列进程支持通过优先级指定处理的队列。举个例子,你可以将高优先级的任务委派到 high (高优先级)队列,从而让它优先执行。

php artisan queue:work --queue=high,default

驱动预备知识

数据库

要使用 database 队列驱动,你需要数据表保存任务信息。要生成创建这些表的迁移,可以运行 Artisan 命令 queue:table,迁移被创建之后,可以使用 migrate 命令生成这些表:

php artisan queue:table

php artisan migrate

Redis

要使用 redis 队列驱动,需要在配置文件 config/database.php 中配置 Redis 数据库连接。

如果 Redis 队列连接使用 Redis Cluster(集群),队列名称必须包含 key hash tag,以确保给定队列对应的所有 Redis keys 都存放到同一个 hash slot:

'redis' => [

'driver' => 'redis',

'connection' => 'default',

'queue' => '{default}',

'retry_after' => 90,

],

注:对一般中小型应用推荐使用 Redis 作为队列驱动。

其他驱动预备知识

如果使用以下几种队列驱动,需要安装相应的依赖:

Amazon SQS: aws/aws-sdk-php ~3.0

Beanstalkd: pda/pheanstalk ~3.0

Redis: predis/predis ~1.0

创建任务

生成任务类

通常,所有的任务类都保存在 app/Jobs 目录。如果 app/Jobs 不存在,在运行 Artisan 命令 make:job 的时候,它将会自动创建。你可以通过 Artisan CLI 来生成队列任务类:

php artisan make:job ProcessPodcast

生成的类都实现了 Illuminate\Contracts\Queue\ShouldQueue 接口, 告诉 Laravel 将该任务推送到队列,而不是立即运行:

f1006f3029a37ce5eb1b4baa89ed70c0.png

任务类结构

任务类非常简单,通常只包含处理该任务的 handle 方法,让我们看一个任务类的例子。在这个例子中,我们模拟管理播客发布服务,并在发布以前上传相应的播客文件:

namespace App\Jobs;

use App\Podcast;

use App\AudioProcessor;

use Illuminate\Bus\Queueable;

use Illuminate\Queue\SerializesModels;

use Illuminate\Queue\InteractsWithQueue;

use Illuminate\Contracts\Queue\ShouldQueue;

class ProcessPodcast implements ShouldQueue

{

use InteractsWithQueue, Queueable, SerializesModels;

protected $podcast;

/**

* 创建任务实例

*

* @param Podcast $podcast

* @return void

*/

public function __construct(Podcast $podcast)

{

$this->podcast = $podcast;

}

/**

* 执行任务

;