laravel job队列

一、数据库建表

  1. 队列任务表

    php artisan queue:table
  2. 任务执行失败表

    php artisan queue:failed-table
    # config/queue.php
     'failed' => [
         'database' => env('DB_CONNECTION', 'mysql'),
         'table' => 'failed_jobs',
     ],
  3. 生成表

    php artisan migrate
  4. 报错信息
    SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes

     <?php
     namespace  App\Providers;
     use Illuminate\Support\ServiceProvider;
     use Illuminate\Support\Facades\Schema;
    
     class  AppServiceProvider  extends  ServiceProvider
     {
         public  function  boot()
         {
             //加这个
             Schema::defaultStringLength(191);
         }
     }

二、创建job类

  1. 创建TestJob
    php artisan make:job TestJob

三、开启队列进程,执行队列任务

  1. 队列优先级

    #我们可以推送任何任务作为消息数据到队列系统,但是不同任务的优先级是不同的,比如一个订单支付任务的优先级肯定是要高于文章浏览数更新这种一般任务,那么如何让队列按照优先级处理不同任务呢?
    php artisan queue:work --queue=payment,default
  2. 实现消息队列的负载均衡

     但是这也会引出另一个问题 ——  如果 payment 队列负载较高,一直处理繁忙状态,那么 default 队列中的任务就会一直阻塞,没有机会执行,为了解决这个问题,一种方案是多开几个同样的处理进程,提高 payment 队列的处理进度:
    
     php artisan queue:work --queue=payment,default
    
     php artisan queue:work --queue=payment,default
    
     php artisan queue:work --queue=payment,default
    
     php artisan queue:work --queue=payment,default
    
     php artisan queue:work --queue=payment,default
    
     但是在业务高峰期,可能这也还是解决不了问题,而且具体要开几个处理进程也是无法准确预判的,要彻底解决这个问题,可以另开几个优先处理 default 队列的进程:
    
     php artisan queue:work --queue=default,payment
    
     php artisan queue:work --queue=default,payment
    
     php artisan queue:work --queue=default,payment
    
     php artisan queue:work --queue=default,payment
    
     php artisan queue:work --queue=default,payment
    
     这样一来,就可以实现消息队列的负载均衡了,前 5 个进程优先处理 payment 队列任务,后 5 个进程优先处理 default 队列任务,如果 payment 为空,则可以全部用于处理 default 队列中的任务。当然了,这里只是一个简单的示例,具体比例如何设置,取决于你自己的业务负载。
  3. 失败任务重试

     这里存在网络请求,网络稳定性无法保证,很有可能出现断网导致请求失败的情况,这个时候,我们就需要对执行失败的任务进行重试,这可以通过在启动处理进程时指定 --tries 选项实现:
    
     php artisan queue:work --queue=service,default --tries=3
    
     这里指定了该进程处理的所有队列任务总的执行次数是 3(第一次运行失败后,还会重试两次)
  4. 重试失败的处理任务

    #failed_jobs的uuid
    php artisan queue:retry 32dbc76c-4f82-4749-b610-a639fe0099b5
    php artisan queue:retry all
  5. 手动发布

    /**
    * 执行任务。
    *
    * @return void
    */
    public function handle()
    {
        $this->release();
    }
  6. 手动使任务失败

    public  function  handle()  { 
        $this->fail(); 
        #如果你想将你的任务标记为由于你捕获的异常而失败,你可以将异常传递给 fail 方法
        $this->fail($exception);
    }
    public function failed()
    {
    }
  7. 守护进程配置
    Supervisor

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /www/wwwroot/xg-laravel/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
user=root
numprocs=8
redirect_stderr=true
stdout_logfile=/var/log/supervisor/laravel/worker.log
stopwaitsecs=3600

其他报错

[root@iZwz939moqxs11634ifZ etc]# supervisorctl reload 
error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib64/python2.7/socket.py line: 224

执行以下命令

/usr/bin/python2 /usr/bin/supervisord -c /etc/supervisord.conf
[root@iZwz939mxs1176gn34ifZ ~]# supervisorctl reload
error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib64/python2.7/socket.py line: 224
[root@iZwz939moqxs1176gn34ifZ ~]# /usr/bin/python2 /usr/bin/supervisord -c /etc/supervisord.conf
Error: The directory named as part of the path /var/log/supervisor/laravel/worker.log does not exist in section 'program:laravel-worker' (file: '/etc/supervisord.d/laravel.ini')
For help, use /usr/bin/supervisord -h
查看报错
cat /var/log/supervisor/laravel/worker.log
#需要php开启禁用函数
pcntl_alarm
pcntl_signal

相关文档

官方文档
centos7安装supervisor以及简单使用

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 4

我有个疑问,在用消息队列负载均衡的时候

有这么一个情况,对接三方接口

  1. 同步订单信息(执行需要 3秒)
  2. 支付成功 (执行需要1 秒)
  3. 申请退款 (执行需要 1秒)

比如用户操作很快,1秒内 3个请求都推送过来了,要如何保证执行顺序呢?

1年前 评论
liaosp 1年前
彭彭 1年前

在sync异步模式中,多job出现串行执行,如何保证按序执行呢(1.支付处理、2.订单处理、3.流水处理)

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!