乐趣区

关于laravel:laravel实现队列

一:队列配置

队列的配置文件搁置在 config/queue.php 文件中,laravel 框架中反对的队列驱动有:sync, database, beanstalkd, sqs, redis,null 对应着:同步(本地应用)驱动,数据库驱动,beanstalkd ,Amazon SQS ,redis,null 队列驱动用于那些放弃队列的工作

1:队列相干配置

(1):队列驱动配置

'default' => env('QUEUE_DRIVER', 'sync'),// 队列驱动设置 

(2):不同驱动相干配置

'connections' => [
    ////syns 驱动配置
    'sync' => ['driver' => 'sync',],
    //// 数据库驱动配置
    'database' => [
        'driver' => 'database',
        'table' => 'jobs',// 数据库驱动配置应用的数据库
        'queue' => 'default',
        'retry_after' => 90,// 指定了工作最多解决多少秒后就被当做失败重试, 比如说,如果这个选项设置为 90,那么当这个工作继续执行了 90 秒而没有被删除,那么它将被开释回队列
    ],
    //beanstalkd 驱动配置
    'beanstalkd' => [
        'driver' => 'beanstalkd',
        'host' => 'localhost',// 应用 beanstalkd 驱动地址
        'queue' => 'default',
        'retry_after' => 90,// 指定了工作最多解决多少秒后就被当做失败重试, 比如说,如果这个选项设置为 90,那么当这个工作继续执行了 90 秒而没有被删除,那么它将被开释回队列
        'block_for' => 0,
    ],
    //sqs 驱动配置
    'sqs' => [
        'driver' => 'sqs',
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
        'queue' => env('SQS_QUEUE', 'your-queue-name'),
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],
    //redis 驱动配置
    'redis' => [
        'driver' => 'redis',
        'connection' => 'default',// 应用哪个连贯的 redis,redis 配置是在 config/database.php 文件中
        'queue' => env('REDIS_QUEUE', 'default'),
        'retry_after' => 90,
        'block_for' => null,
    ],

],

2:不同队列依赖

(1):数据库驱动

应用数据库驱动须要生成一个队列驱动表

php artisan queue:table
php artisan migrate

执行下面的命令之后会发现数据库中会减少一个 jobs 表

(2):redis 驱动

应用 redis 驱动须要装置一个 predis/predis 拓展

composer require predis/predis

(3):Amazon SQS 驱动

应用 Amazon SQS 驱动时须要装置 aws/aws-sdk-php 拓展

composer require aws/aws-sdk-php

(4):Beanstalkd 驱动

应用 Beanstalkd 驱动须要装置 pda/pheanstalk 拓展

composer require pda/pheanstalk

二:创立队列工作

php artisan make:job TestJobs

执行下面的命令创立一个队列工作类,这时候会发现在 app/jobs 目录下生成一个 TestJobs.php 文件

简略的队列工作类实例:

<?php
namespace App\Jobs;
use App\Models\blog\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class TestJobs implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    /**
     * 工作最大尝试次数。*
     * @var int
     */
    public $tries = 5;
    /**
     * 工作运行的超时工夫。* 指定了 Laravel 队列处理器最多执行多长时间后就应该被敞开掉
     * --timeout 应该永远都要比 retry_after 短至多几秒钟的工夫。这样就能保障工作过程总能在失败重试前就被杀死了。* 如果你的 --timeout 选项大于 retry_after 配置选项,你的工作可能被执行两次
     *
     * @var int
     */
    public $timeout = 120;
    public $info;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($info)
    {
        //
        $this->info = $info;
    }
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
        $user = new User();
        $user->user_no = $this->info['user_no'];
        $user->user_name = $this->info['user_name'];
        $user->save();}
}

三:工作散发

1:默认散发

$info = [
    'user_no'=>'006',
    'user_name'=>'testName'
];
TestJobs::dispatch($info);

2:延时散发

TestJobs::dispatch($info)->delay(Carbon::now()->addMinutes(10));// 示意延时十分钟散发工作 

3:指定队列散发

TestJobs::dispatch($info)->onQueue('processing');// 示意应用默认驱动的 processing 队列 

4:指定驱动散发

TestJobs::dispatch($info)->onConnection('redis');// 应用 redis 驱动的默认队列 

5:指定驱动和队列散发

TestJobs::dispatch($info)->onConnection('redis')->onQueue('processing');// 应用 redis 驱动的 processing 队列 

四:工作解决

php artisan queue:work

执行后咱们会发现 user 表中发现多了一条 user_no 为 006,user_name 为 testName 数据,然而如果你指定了驱动和队列的话,这时候执行 php artisan queue:work,你就会发现数据库中没有数据加进去,这是因为 php artisan queue:work 命令是对默认驱动和 ’default’ 队列监听,这时候就要应用:

php artisan queue:work redis --queue="processing"  //redis 示意指定驱动 processing 示意指定队列 

五:失败工作解决

php artisan queue:failed-table
php artisan migrate

执行下面命令后会在数据库中减少一张 failed_jobs 表,专门用于存储失败的工作信息,在 TestJobs 类中增加一个 failed 办法解决失败队列

/**
 * 要解决的失败工作。*
 * @param  Exception  $exception
 * @return void
 */
public function failed(Exception $exception)
{// 给用户发送失败告诉,等等...}

如果你想要注册一个只有当队列工作失败时就会被调用的事件,咱们能够在 Laravel 的 app/Providers/AppServiceProvider.php 文件中对这个事件附加一个回调函数即可

/**
 * 启动任意应用程序的服务。*
 * @return void
 */
public function boot()
{Queue::failing(function (JobFailed $event) {
        // $event->connectionName
        // $event->job
        // $event->exception
    });
}

六:应用 Supervisor 治理队列

一旦应用 queue:work 命令,它将始终运行,直到你手动进行或者你敞开控制台,如果你想要让 queue:work 命令永恒在后盾运行,这时候能够应用过程监控工具 Supervisor 来实现永恒在后盾运行

1:Supervisor 装置

Supervisor 装置能够参考:https://segmentfault.com/a/11…

2:配置 Supervisor

(1):配置 supervisord.conf

在 /etc/supervisord.conf 文件的最初一行减少

files = supervisord.d/*.ini

(2):队列过程配置

在 /etc/supervisord.d/ 目录下创立一个.ini 文件

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/app.com/artisan queue:work database --sleep=3 --tries=3  #/home/forge/app.com 为我的项目地址
autostart=true
autorestart=true
user=forge
numprocs=8 #numprocs 命令会要求 Supervisor 运行并监控 8 个 queue:work 过程
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log

3:启动 Supervisor

systemctl start supervisord.service
supervisorctl update
supervisorctl reload
supervisorctl start laravel-worker
退出移动版