laravel 队列操作queue

使用场景:
有些任务并不需要及时运行,就可以将其写入队列,从而不影响主业务逻辑的进程。
如:此篇博文发布成功后推送消息给其关注的用户。假如粉丝很多,肯定不能将发布博文与推送通知的逻辑捆绑在一起,不然服务器资源卡死。

下面简单介绍如何使用

1.配置队列(config/queue.php)
框架所支持的队列驱动的配置都有。包括:database,Beanstalkd,Amazon SQS,Redis,和一个同步(本地使用)的驱动。还有一个名为 null 的驱动表明不使用队列任务。

ps:这里的队列驱动 可以理解为存储队列任务的载体 :下面截图介绍
2.在.env 文件中配置使用的队列(此处以redis做演示)

QUEUE_DRIVER=redis

3.创建队列表(cmd运行)

php artisan queue:table(以database为驱动要运行,redis驱动数据直接插入redis)
php artisan migrate
php artisan queue:failed-table
php artisan migrate

简单介绍: 第一步会新建
database/migrations/{timestamp}_create_failed_jobs_table.php 文件(表结构)
接着使用 migrate 命令生成表
laravel 队列操作queue_第1张图片
失败任务#
有时候队列中的任务会失败。Laravel 内置了一个方便的方式来指定任务重试的最大次数。当任务超出这个重试次数后,它就会被插入到 failed_jobs 数据表里面
###最后运行成功,会在数据库中出现如下表:
在这里插入图片描述

4.配置队列任务最大重试次数,或者单任务最大执行时间,有两种方法

方法一:artisan命令,增加—tries或者 —timeout
php artisan queue:listen --tries=3 //失败任务尝试3次
php artisan queue:listen --timeout=60 //每个任务运行最大时间不超过60秒
方法二:在Job控制器,任务类中加入变量定义
laravel 队列操作queue_第2张图片
PS:优先级
当在类配置了,那么 artisan命令的配置将无效,即任务类配置优先

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

php artisan make:job SendEmail

该命令会在 app/Jobs 目录下生成一个新的类:
app/Jobs/SendEmail.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 Exception;

class SendEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
	
	/**
     * 任务最大尝试次数。
     *
     * @var int
     */
    public $tries = 3;
    /**
     * 任务运行的超时时间。
     *
     * @var int
     */
    public $timeout = 180;
	
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {   
        
        try {  
			$error = 'Always throw this error';  
			throw new Exception($error);  
				// 从这里开始,tra 代码块内的代码将不会被执行  
			echo 'Never executed';  
			file_put_contents(storage_path('logs/queue.log'),'['.date('Y-m-d : h:i:s',time()).']'.'队列执行success'."\r\n",FILE_APPEND);
		} catch (Exception $e) {  
			echo 'Caught exception: ',  $e->getMessage(),'
'
; } } }

6.任务下发

再控制器中直接使用
SendEmail::dispatch();
注意:要引入SendEmail 类
use App\Jobs\SendEmail;

7.测试(监听队列任务)

php artisan queue:listen

如果还未监听 运行第六部会将任务一直存储在队列驱动的数据库里
如:
redis
laravel 队列操作queue_第3张图片
或者database
在这里插入图片描述
当运行第七步,运行队列,会依次执行
由于此处我设置了tries=3 并且在job类里注释了// use Exception;
队列任务会在尝试三次后失败写入failed_job表中

在这里插入图片描述

最后 补充一点
在app\Providers\AppServiceProvider.php中

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Queue;
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Queue::before( function (JobProcessing $event) {
            \Log::info("处理任务前");
            
        });
         Queue::after( function (JobProcessed $event) {
            \Log::info("处理任务后");
           
        });
    }
}

boot方法中添加after before 会在队列任务执行前后 先做处理

你可能感兴趣的:(laravel,队列,laravel)