队列
设定
Laravel 队列组件提供了一个统一的队列服务API,队列允许您将一个任务延后执行,例如可以将邮件延后至您指定的时间再发送,进而大幅的加快您开发网站应用程序的效率。
队列的配置文件在 app/config/queue.php
,在这个文件里您将可以找到框架中每种不同的队列服务的连接配置,其中包含了 Beanstalkd,IronMQ,Amazon SQS,Redis,以及同步(本地端使用)驱动设定。
下列的 composer.json 表示您的队列服务所需要的依赖环境:
- Beanstalkd:
pda/pheanstalk ~3.0
- Amazon SQS:
aws/aws-sdk-php
- IronMQ:
iron-io/iron_mq
基本用法
推送一个工作至队列
要推送一个新的工作至队列,请使用 Queue::push
方法:
Queue::push('SendEmail', array('message' => $message));
定义一个工作处理程序
push
方法的第一个参数为应该处理这个工作的类方法名称,第二个参数是一个要传递至处理程序的数组,一个工作处理程序应该参照下列定义:
class SendEmail {
public function fire($job, $data)
{
//
}
}
注意如果您未在第一个参数指定工作处理的类及方法(如 SendEmail@process),那 fire
为类中默认必需的方法用来接收被推送至队列 Job
实例以及 data
。
指定一个特定的处理程序方法
假如您想要用一个 fire
以外的方法处理工作,您可以在推送工作时指定方法如下:
Queue::push('SendEmail@send', array('message' => $message));
指定队列使用特定连接
您也可指定队列工作送至指定的连接:
Queue::push('SendEmail@send', array('message' => $message), 'emails');
发送相同的数据去多个连接
如果您需要传送一样的数据去几个不同的队列服务器,您也可以使用 Queue::bulk
方法:
Queue::bulk(array('SendEmail', 'NotifyUser'), $payload);
延迟执行一个工作
有时后您也希望延迟一个队列工作的执行,举例来说您希望一个队列工作在客户注册 15 分钟后发送一个 e-mail,您可以使用 Queue::later
方法来完成这件事情:
$date = Carbon::now()->addMinutes(15);
Queue::later($date, 'SendEmail@send', array('message' => $message));
在这个例子中,我们使用 Carbon 日期函数库来指定我们希望队列工作希望延迟的时间,另外您也可传送一个 整数来设定您希望延迟的秒数。
The Amazon SQS 服务有 900s 的延迟限制 (15 分钟)。
删除一个处理中的工作
当您已经开始处理完成一个队列工作,它就必需在队列中删除,我们可以通过 Job
实例中的 delete
方法来完成这件事:
public function fire($job, $data)
{
// Process the job...
$job->delete();
}
释放一个工作回到队列中
假如您希望将一个工作释放回队列之中,您可以通过 release
方法来完成这件事情:
public function fire($job, $data)
{
// Process the job...
$job->release();
}
您也可以指定秒数来让这个工作延迟释放:
$job->release(5);
检查工作执行次数
当一个工作执行后发生错误,这个工作将会自动的释放回队列当中,您可以通过 attempts
方法来检查这个工作已经被执行的次数:
if ($job->attempts() > 3)
{
//
}
取得一个工作的 ID
您也 可以取得这个工作的识别码:
$job->getJobId();
队列闭包
您也可以推送一个闭包去队列,这个方法非常的方便及快速的来处理需要使用队列的简单的任务:
Queue::push(function($job) use ($id)
{
Account::delete($id);
$job->delete();
});
要让一个组件变量可以在队列闭包中可以使用我们会通过 use
命令,试着传送主键及重复使用的相关模组在您的队列工作中,这可以避免其他的序列化行为。
当使用 Iron.io push queues 时,您应该在队列闭包中采取一些其他的预防措施,我们应该在执行工作收到队列数据时检查token是否真来自 Iron.io,举例来说您推送一个队列工作到 https://yourapp.com/queue/receive?token=SecretToken
,接下来在您的工作收到队列的请求时,您就可以检查token的值是否正确。
执行一个队列监听
Laravel 内含一个 Artisan 命令,它将推送到队列的工作拉来下执行,您可以使用 queue:listen
命令,来执行这件常驻任务:
开始队列监听
php artisan queue:listen
您也可以指定特定队列连接让监听器使用:
php artisan queue:listen connection
注意当这个任务开始时,这将会一直持续执行到他被手动停止,您也可以使用一个处理监控如 Supervisor 来确保这个队列监听不会停止执行。
您也可以在 listen
命令中使用逗号分隔不同的队列连接来设定队列的重要性:
php artisan queue:listen --queue=high,low
在这个范列中 high-connection
将总是会优先处理队列的工作,相对于 low-connection
指定工作超时参数
您也可以设定给每个工作允许执行的秒数:
php artisan queue:listen --timeout=60
指定队列休息时间
此外,您也可以指定让监听器在拉取新工作时要等待几秒:
php artisan queue:listen --sleep=5
注意队列只会在没有队列内容时停止工作,假如队列中仍有许多可执行的工作,队列监听将持续不中断的处理
处理队列上的一个工作
当您只想处理队列上的一个工作您可以使用 queue:work
命令:
php artisan queue:work
常驻队列处理器
queue:work
也包含了一个 --daemon
选项能强迫队列处理器可以持续处理工作,即使框架重新启动了也不会停止。这种方式比起 queue:listen
来说,可以更有效的减少CPU的使用量,不过代价是要增加了您布署时的复杂性。
当开始一个队列处理器处于常驻模式,使用 --daemon
标示:
php artisan queue:work connection --daemon
php artisan queue:work connection --daemon --sleep=3
php artisan queue:work connection --daemon --sleep=3 --tries=3