page contents

Laravel异步队列全攻略

最近项目需求,研究了laravel的异步队列。官方文档虽然很是详细,但也有些晦涩难懂,在此记录下步骤,供大家参考。

attachments-2020-04-L6CbQgUe5ea12f5ea9d7e.jpg

最近项目需求,研究了laravel的异步队列。

官方文档虽然很是详细,但也有些晦涩难懂,在此记录下步骤,供大家参考。


1、修改/config/queue.php文件

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Queue Connection Name
    |--------------------------------------------------------------------------
    |
    | Laravel's queue API supports an assortment of back-ends via a single
    | API, giving you convenient access to each back-end using the same
    | syntax for every one. Here you may define a default connection.
    |
    */

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

    /*
    |--------------------------------------------------------------------------
    | Queue Connections
    |--------------------------------------------------------------------------
    |
    | Here you may configure the connection information for each server that
    | is used by your application. A default configuration has been added
    | for each back-end shipped with Laravel. You are free to add more.
    |
    | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
    |
    */

    'connections' => [

        'sync' => [
            'driver' => 'sync',
        ],

        'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'retry_after' => 90,
        ],

        'beanstalkd' => [
            'driver' => 'beanstalkd',
            'host' => 'localhost',
            'queue' => 'default',
            'retry_after' => 90,
            'block_for' => 0,
        ],

        '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' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => env('REDIS_QUEUE', 'default'),
            'retry_after' => 90,
            'block_for' => null,
        ],

    ],

    /*
    |--------------------------------------------------------------------------
    | Failed Queue Jobs
    |--------------------------------------------------------------------------
    |
    | These options configure the behavior of failed queue job logging so you
    | can control which database and table are used to store the jobs that
    | have failed. You may change them to any database / table you wish.
    |
    */

    'failed' => [
        'database' => env('DB_CONNECTION', 'mysql'),
        'table' => 'failed_jobs',
    ],

];

注意:修改.env文件如下参数,设置队列连接默认为数据库连接

QUEUE_CONNECTION=database


2、新建/app/Job/EmailJob.php,此文件为队列主文件

<?php
namespace App\Job;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Service\EmailService;
class EmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    private $content,$to;
    public function __construct($content,$to){
        $this->content=$content;
        $this->to=$to;
    }
    public function handle(){
        $res=false;
        $times=0;
        while($res!==true && $times<3){
            try{
                $times++;
                $res=EmailService::send($this->content,$this->to);
            }catch (\Exception $e){
                Log::error(date('Y-m-d h:i:s',time()).' send email error:'.$e->getMessage());
            }
        }
        if($res===true){
            Log::info(date('Y-m-d h:i:s',time()).' send email success:');
        }
    }
}


3、新建/app/Service/EmailJobService.php服务,此文件为封装服务文件,可以不用,直接在使用的地方调用队列。

<?php
namespace App\Service;
use App\Job\EmailJob;
class EmailJobService
{
    public static function add($content,$to){
        $job=new EmailJob($content,$to);
        dispatch($job);
    }
}


4、打开终端切换目录进入Laravel项目根目录,执行如下命令,创建队列任务需要的数据表。

php artisan queue:table

php artisan queue:failed-table

php artisan migrate


5、通过下面这条指令启动队列监听服务,它会自动处理 jobs 表中的队列任务。

php artisan queue:listen

监听指定队列:

php artisan queue:work --queue=default,mytask --tries=2

这是监听 default和mytask两个队列,区分先后顺序。


6、如果需要在linux中后台运行,有两种方法:

6.1 执行如下命令:

nohup php artisan queue:listen > /tmp/artisan.log 2>&1 &

6.2.1 安装Supervisor,我的服务器系统为CentOs7.5,所以使用yum安装。

yum install supervisor

6.2.2 在/etc/supervisord.d下新建ini文件,eg:laraver-worker.ini,设置自动运行命令等相关参数

[program:laravel-worker]

process_name=%(program_name)s_%(process_num)02d

command=php 这里需要写项目目录/artisan queue:work --sleep=3 --tries=3

autostart=true

autorestart=true

user=root

numprocs=8

stdout_logfile=/root/queue/daily_english_queue.log

6.2.3 启动supervisor,laravel队列监听进程便在后台运行了。

supervisord -c /etc/supervisord.conf


7、注意:如果修改了job内的代码(包括job调用的方法类),是需要重启queue的。

php artisan queue:restart



attachments-2020-04-Q45FJXUJ5ea12f35c803e.jpg

  • 发表于 2020-04-23 14:02
  • 阅读 ( 610 )
  • 分类:PHP开发

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章