laravel5.4-队列任务简单实例

一、先简单的说明下为什么要是用队列任务,因为公司项目涉及到了发邮件的功能,而邮件服务代理商和项目服务器在两个不同的国家,客户端上有发邮件的功能都会反应好几秒,因此想把发邮件这种实时性要求不高的功能单独拿出来,通过队列任务异步发送。

1、大致思路:

当功能中遇到发邮件的需求,将该发送请求包含的必要参数记录至某个队列中(mysql、redis、file均可)。

开启一个守护进程,一直监控该任务队列,发现有任务进来后,获取任务数据,然后发送邮件,发送成功或失败都进行相应的通知动作。

二、正式开始

1、配置

首先查看laravel配置文件config/queue.php,可以看到如下,sync表示会默认执行,非等待队列任务,如果使用队列任务必须要修改该值,并且.env文件中的配置也一定要改。

'default' => env('QUEUE_DRIVER', 'sync')

connections数组中可以看到很多直接的队列方式,database,redis,sqs等,有一些还需要安装拓展插件才能使用,我们这里就使用比较不费事的database作为实践,各默认配置含义如下

'database' => [
    'driver' => 'database',
    'table' => 'jobs',//记录队列任务的表名
    'queue' => 'default',//默认任务名
    'retry_after' => 90,//任务在运行 90 秒后还未完成,那么将被释放回队列而不是删除掉。
],

.evn中配置为database方式之后,我们需要创建几个队列任务所依赖的表,命令如下:

php artisan queue:table
php artisan migrate

为了方便记录任务执行失败后的结果,我们把失败记录表也创建出来

php artisan queue:failed-table
php artisan migrate

这几张表就是创建出来的table,数据库准备完毕后我们就可以对代码动手了。

2、代码开始

2.1首先我们需要创建任务类,可以直接通过artisan命令创建,也可以手动创建,命令如下

php artisan make:job TestQueue

会在app目录下看到产生一个Jobs目录以及TestQueue.php文件,代码编辑从这里开始

class TestQueue implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries=3;//指定任务最大失败次数,级别高于启动的设置值
    public $timeout=30;//任务最大的执行时间,级别高于启动设置值
    protected $data;//任务传值

    /**
     * 通常用于创建任务时的传值
     * Create a new job instance.
     * @return void
     */
    public function __construct($data)
    {
        $this->data=$data;
    }

    /**
     * 执行任务:去任务队列中获取任务,然后执行代码,执行完毕后删除队列中的任务
     * Execute the job.
     * @return void
     */
    public function handle()
    {
        DB::table('test')->insert($this->data);
    }

    /**任务失败时执行该方法
     * @param Exception $e
     */
    public function failed(Exception $e)
    {
        // 比如短信通知管理员或记录日志等
    }
}

2.2、创建控制器方法,实现队列

<?php
namespace App\Http\Controllers;

use App\Jobs\TestQueue;
use Carbon\Carbon;
use Illuminate\Support\Facades\Request;

class SendController extends Controller{


    /**
     * 当上面的任务类完成之后,我们就可以启动一个守护进程等待任务进入队列了
     * php artisan queue:work  启动队列进程
     * php artisan queue:restart  平滑重启
     * php artisan queue:work --tries=3   指定失败次数,也可以在类中指定
     * php artisan queue:work --timeout=30  队列任务执行的最大时间(秒)
     * php artisan queue:work --queue=name  指定该进程处理的队列名,只会处理该name的队列
     * php artisan queue:work redis 指定驱动连接
     * php artisan queue:work --sleep=3  我们可以使用 sleep 配置项来指定没有新的有效任务产生时的休眠时间
     */
    public function test_set(Request $request){
        //给对应数据库中插入数据
        $arr=[
            'name'=>substr(md5(time()),0,10),
            'age'=>rand(10,100),
            'tel'=>time()
        ];

        $job=new TestQueue($arr);//最基本的任务创建,采用默认参数

        $job=(new TestQueue($arr))
            ->delay(Carbon::now()->addMinutes(1));//任务创建1分钟后执行,最多15分钟

        $job=(new TestQueue($arr))
            ->onQueue('name');//任务创建至指定队列,启动的进程也需要queue=name指定名字

        $job=(new TestQueue($arr))
            ->onConnection('sqs');//任务使用不同的驱动链接,当然可以指定任务连接和队列

        dispatch($job);
    }
}

最后我们要把守护进程启动,这才是执行队列任务的动作核心

php artisan queue:work

试着执行该路由方法后,查看数据库中就会有对应数据产生了,这就是最简单的队列任务,发短信、发邮件、发通知等实时性不要求很高的都可以采用队列任务实现。

                             你们的支持是我前进的动力,感谢来访!

1条评论

发表评论