zoukankan      html  css  js  c++  java
  • Laravel之队列

    一.配置

    队列配置文件存放在config/queue.php 。在该文件中你将会找到框架自带的每一个队列驱动的连接配置,包括数据库、Beanstalkd、 IronMQ、 Amazon SQS、 Redis 以及同步(本地使用)驱动。其中还包含了一个 null 队列驱动以拒绝队列任务。

    默认是sync,即同步的,直接处理,无队列.要将其修改为对应的类型,如database等

    二.依赖

    1.数据库依赖
    为了使用database 队列驱动,需要一张数据库表来存放任务,要生成创建该表的迁移,运行 Artisan 命令queue:table ,迁移被创建好了之后,使用migrate 命令运行迁移:

    php artisan queue:table
    php artisan migrate
    

      

    2.其他队列类型依赖
    下面是以上列出队列驱动需要安装的依赖:
    • Amazon SQS: aws/aws-sdk-php ~3.0
    • Beanstalkd: pda/pheanstalk ~3.0
    • IronMQ: iron-io/iron_mq ~2.0
    • Redis: predis/predis ~1.0

    三.生成任务类

    1.默认情况下,应用的所有队列任务都存放在app/Jobs 目录。你可以使用 Artisan CLI 生成新的队列任务:

    php artisan make:job SendReminderEmail --queued
    

      

    该命令将会在app/Jobs 目录下生成一个新的类,并且该类实现了IlluminateContractsQueueShouldQueue接口,--queued告诉 Laravel 该任务应该被推送到队列而不是同步运行。

    2.SendReminderEmail.php代码如下:

    <?php
    
    namespace AppJobs;
    
    use IlluminateSupportFacadesLog;
    use AppJobsJob;
    use IlluminateQueueSerializesModels;
    use IlluminateQueueInteractsWithQueue;
    use IlluminateContractsBusSelfHandling;
    use IlluminateContractsQueueShouldQueue;
    use AppModelsUser;
    
    class SendReminderEmail extends Job implements SelfHandling, ShouldQueue
    {
        use InteractsWithQueue, SerializesModels;
    
        protected $user;
        /**
         * Create a new job instance.
         *
         * @return void
         */
        public function __construct(User $user)
        {
            $this->user = $user;
        }
    
        /**
         * 处理任务.
         *
         * @return void
         */
        public function handle()
        {
            Log::alert('我是来自队列,发送了一个邮件',['id' => $this->user->id, 'name' => $this->user->name]);
        }
    }
    

      

    3.任务发生异常
    a.任务在处理的时候发生异常,任务将被放回队列.在下一次再被处理
    b.判断同一任务失败的次数
    $this->attempts() // 返回失败次数
    $this->release(50); // 将任务放回到队列,50秒后次执行

    四.推送任务

    1.控制器中:

    $user = Auth::user();
    $this->dispatch((new SendReminderEmail($user))->delay(60)); //delay表示延迟队列执行
    
    // 也可以将任务推送到不同的队列中
    $this->dispatch((new SendReminderEmail($user))->onQueue('jobs'));
    
    // 也可以从请求中分发任务
    $this->dispatchFrom('AppJobsProcessOrder', $request, [附加的参数]);
    

      

    2.其他地方使用 

    use DispatchesJobs;
    ......
    $this->dispatch()
    

      

    五.启动队列监听

    1.基本命令

    php artisan queue:listen connection_name --queue=queue_name
    
    php artisan queue:listen connection //指定连接,也就是不同队列类型,如database,redis,在queue.php中配置
    
    php artisan queue:listen --queue=high,low //指定队列优先级,比如有限处理某队列,多个队列用,分割
    
    php artisan queue:listen --timeout=60 //每个任务运行最大时间不超过60秒
    
    php artisan queue:listen --sleep=5 //没有任务的时候休眠5秒
    
    php artisan queue:listen --tries=3 //失败任务尝试3次
    

     

    queue:work 默认只执行一次队列请求, 当请求执行完成后就终止;
    queue:listen 监听队列请求,只要运行着,就能一直接受请求,除非手动终止;

     

    2.作为系统进程运行

    Supervisor

    Supervisor 配置文件通常存放在/etc/supervisor/conf.d 目录,在该目录中,可以创建多个配置文件指示 Supervisor 如何监视进程,例如,让我们创建一个开启并监视queue:work 进程的laravel-worker.conf 文件:

    [program:laravel-worker]
    process_name=%(program_name)s_%(process_num)02d
    command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 --daemon
    autostart=true
    autorestart=true
    user=forge
    numprocs=8
    redirect_stderr=true
    stdout_logfile=/home/forge/app.com/worker.log
    

      

    在本例中, numprocs 指令让 Supervisor 运行 8 个queue:work 进程并监视它们,如果失败的话自动重启。配置文件创建好了之后,可以使用如下命令更新 Supervisor 配置并开启进程:

    sudo supervisorctl reread
    sudo supervisorctl update
    sudo supervisorctl start laravel-worker:*
    

      

    3.后台队列(守护进程)

    Artisan 命令queue:work 包含一个--daemon 选项来强制队列 worker 持续处理任务而不必重新启动框架。相较于queue:listen 命令该命令对 CPU 的使用有明显降低:

    php artisan queue:work connection --daemon
    php artisan queue:work connection --daemon --sleep=3
    php artisan queue:work connection --daemon --sleep=3 --tries=3
    

      

    正如你所看到的, queue:work 任务支持大多数queue:listen 中有效的选项。你可以使用php artisan help queue:work 任务来查看所有有效选项。

    注意点:
    1.后台队列 worker 在处理每个任务时不重启框架,因此,你要在任务完成之前释放资源,举个例子,如果你在使用 GD 库操作图片,那么就在完成时使用imagedestroy 释放内存。类似的,数据库连接应该在后台长时间运行完成后断开,你可以使用DB::reconnect 方法确保获取了一个新的连接。

    2.如果修改了代码,在后台队列中是无效的,必须重启队列
    php artisan queue:restart
    这个命令依赖于缓存系统重启进度表,默认情况下,APC 在 CLI 任务中无法正常工作,如果你在使用 APC,需要在 APC 配置中添加apc.enable_cli=1 。

    六.处理失败任务

    1.创建一个 failed_jobs 表的迁移

    php artisan queue:failed-table
    

      

    2.生成表

    php artisan migrate
    

      

    3.加重试次数限制

    php artisan queue:listen connection-name --tries=3
    

      

    超过3次的任务将被移到failed_jobs表

    4.也可以手动删除一个任务

    if ($this->attempts() == 1) {
                $this->delete();
    }
    

      

    5.添加失败任务事件

    a.AppServiceProvider中添加

    /**
    * 启动应用服务
    *
    * @return void
    */
    public function boot()
    {
    	Queue::failing(function ($connection, $job, $data) {
    	// Notify team of failing job...
    	});
    }
    

      

    b.在任务类中添加

    /**
    * 执行任务
    *
    * @param Mailer $mailer
    * @return void
    */
    public function handle(Mailer $mailer)
    {
    	//
    }
    
    /**
    * 处理失败任务
    *
    * @return void
    */
    public function failed()
    {
    	// Called when the job is failing...
    }
    

      

    6.重试失败任务

    a.查看失败的任务
    php artisan queue:failed
    
    b.重新执行失败任务
    php artisan queue:retry 5 //重新执行id为5的失败任务
    
    c.删除失败任务
    php artisan queue:forget 5 //删除id为5的失败任务
    
    d.删除所有任务
    php artisan queue:flush
    

      

    总体而言,任务和事件的相同之处都是需要触发/推送;不同之处可能在于,任务一般是耗时操作,放入队列较好;事件一般不是耗时操作,当然事件也可以是耗时操作,也能放入队列.

  • 相关阅读:
    .NET Core SignalR 和 .NET SignalR 区别
    MySQL 连接出现 Authentication plugin 'caching_sha2_password' cannot be loaded
    Geohash 基本知识及 .NET 下计算相邻8个区域编码
    ASP.NET 下配置请求大小、请求时间等参数
    .NET Core、EF、Dapper、MySQL 多种方式实现数据库操作(动态注册实体类)
    .NET Core 开发常用命令(VS Code)
    ping
    exec与xargs区别
    doc转docx
    读取docx表格中的信息
  • 原文地址:https://www.cnblogs.com/itfenqing/p/6934184.html
Copyright © 2011-2022 走看看