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
    

      

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

  • 相关阅读:
    Binary Tree Inorder Traversal
    Populating Next Right Pointers in Each Node
    Minimum Depth of Binary Tree
    Majority Element
    Excel Sheet Column Number
    Reverse Bits
    Happy Number
    House Robber
    Remove Linked List Elements
    Contains Duplicate
  • 原文地址:https://www.cnblogs.com/itfenqing/p/6934184.html
Copyright © 2011-2022 走看看