1.简介
Laravel 队列服务为各种不同的后台队列提供了统一的API。队列允许你推迟耗时任务(例如发送邮件)的执行,从而大幅提高web请求速度。
配置
队列配置文件存放在config/queue.php
。在该文件中你将会找到框架自带的每一个队列驱动的连接配置,包括数据库、Beanstalkd、 IronMQ、 Amazon SQS、 Redis以及同步(本地使用)驱动。其中还包含了一个null队列驱动以拒绝队列任务。
database
为了使用database队列驱动,需要一张数据库表来存放任务,要生成创建该表的迁移,运行Artisan命令queue:table,迁移被创建好了之后,使用migrate命令运行迁移:
1 | php artisan queue:table |
其它队列依赖
- Amazon SQS: aws/aws-sdk-php ~3.0
- Beanstalkd: pda/pheanstalk ~3.0
- Redis: predis/predis ~1.0
2.生成Job类
2.1Job任务类都存在app/Jobs
目录中, 可以使用命令行生成命令
1 | php artisan make:job SendEmail |
该命令将会在app/Jobs目录下生成一个新的类,并且该类实现了Illuminate\Contracts\Queue\ShouldQueue接口,告诉Laravel该任务应该被推送到队列而不是同步运行。
2.2 SendEmail文件结构
1 |
|
注:我们能够直接将Eloquent模型传递到对列任务的构造函数中。由于该任务使用了SerializesModels trait,Eloquent模型将会在任务被执行是优雅地序列化和反序列化。如果你的队列任务在构造函数中接收Eloquent模型,只有模型的主键会被序列化到队列,当任务真正被执行的时候,队列系统会自动从数据库中获取整个模型实例。这对应用而言是完全透明的,从而避免序列化整个Eloquent模型实例引起的问题。
handle方法在任务被队列处理的时候被调用,注意我们可以在任务的handle方法中进行依赖注入。Laravel服务容器会自动注入这些依赖。
2.3手动释放任务
如果你想要手动释放任务,生成的任务类中自带的InteractsWithQueue trait提供了释放队列任务的release方法,该方法接收一个参数——同一个任务两次运行之间的等待时间:
1 | public function handle(Mailer $mailer){ |
2.4检查尝试运行次数
正如上面提到的,如果在任务处理期间发生异常,任务会自动释放回队列中,你可以通过attempts方法来检查该任务已经尝试运行次数:
1 | public function handle(Mailer $mailer){ |
3 推送任务到队列
1 | Route::get('/', function () { |
3.1 DispatchesJobs Trait
当然,有时候你想要从应用中路由或控制器之外的某些地方分发任务,因为这个原因,你可以在应用的任何类中包含DispatchesJobs trait
,从而获取对分发方法的访问,举个例子,下面是使用该trait的示例类:
1 |
|
3.2 dispatch方法
或者,你也可以使用全局的dispatch方法:
1 | Route::get('/job', function () { |
3.3 为任务指定队列
1 | Route::get('/', function () { |
3.4 延迟任务
有时候你可能想要延迟队列任务的执行。例如,你可能想要将一个注册15分钟后给消费者发送提醒邮件的任务放到队列中,可以通过使用任务类上的delay方法来实现,该方法由Illuminate\Bus\Queueable
trait提供:
1 | Route::get('/', function () { |
3.5 任务事件
Queue::after
方法允许你在队列任务执行成功后注册一个要执行的回调函数。在该回调中我们可以添加日志、统计数据。例如,我们可以在Laravel内置的 AppServiceProvider
中添加事件回调:
1 |
|
4 运行队列监听器
使用 queue:listen 命令运行监听器:1
php artisan queue:listen
还可以指定监听器使用哪个队列连接:
1 | php artisan queue:listen connection |
注:一旦任务开始后,将会持续运行直到手动停止。你可以使用一个过程监视器如Supervisor来确保队列监听器没有停止运行。
4.1 队列优先级
你可以传递逗号分隔的队列连接列表到listen任务来设置队列优先级:
1 | php artisan queue:listen --queue=high,low |
在本例中,high队列上的任务总是在从low队列移动任务之前被处理。
4.2 指定任务超时参数
你还可以设置每个任务允许运行的最大时间(以秒为单位):
1 | php artisan queue:listen --timeout=60 |
4.3 指定队列睡眠时间
此外,可以指定轮询新任务之前的等待时间(以秒为单位):
1 | php artisan queue:listen --sleep=5 |
注:需要注意的是队列只会在队列上没有任务时“睡眠”,如果存在多个有效任务,该队列会持续运行,从不睡眠。