laravel job队列
一、数据库建表
队列任务表
php artisan queue:table
任务执行失败表
php artisan queue:failed-table
# config/queue.php 'failed' => [ 'database' => env('DB_CONNECTION', 'mysql'), 'table' => 'failed_jobs', ],
生成表
php artisan migrate
报错信息
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类
- 创建TestJob
php artisan make:job TestJob
三、开启队列进程,执行队列任务
队列优先级
#我们可以推送任何任务作为消息数据到队列系统,但是不同任务的优先级是不同的,比如一个订单支付任务的优先级肯定是要高于文章浏览数更新这种一般任务,那么如何让队列按照优先级处理不同任务呢? php artisan queue:work --queue=payment,default
实现消息队列的负载均衡
但是这也会引出另一个问题 —— 如果 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 队列中的任务。当然了,这里只是一个简单的示例,具体比例如何设置,取决于你自己的业务负载。
失败任务重试
这里存在网络请求,网络稳定性无法保证,很有可能出现断网导致请求失败的情况,这个时候,我们就需要对执行失败的任务进行重试,这可以通过在启动处理进程时指定 --tries 选项实现: php artisan queue:work --queue=service,default --tries=3 这里指定了该进程处理的所有队列任务总的执行次数是 3(第一次运行失败后,还会重试两次)
重试失败的处理任务
#failed_jobs的uuid php artisan queue:retry 32dbc76c-4f82-4749-b610-a639fe0099b5 php artisan queue:retry all
手动发布
/** * 执行任务。 * * @return void */ public function handle() { $this->release(); }
手动使任务失败
public function handle() { $this->fail(); #如果你想将你的任务标记为由于你捕获的异常而失败,你可以将异常传递给 fail 方法 $this->fail($exception); } public function failed() { }
守护进程配置
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
相关文档
本作品采用《CC 协议》,转载必须注明作者和本文链接
我有个疑问,在用消息队列负载均衡的时候
有这么一个情况,对接三方接口
比如用户操作很快,1秒内 3个请求都推送过来了,要如何保证执行顺序呢?
在sync异步模式中,多job出现串行执行,如何保证按序执行呢(1.支付处理、2.订单处理、3.流水处理)