Laravel使用Queue队列的技巧汇总


Posted in PHP onSeptember 02, 2019

前言

Laravel 队列为不同的后台队列服务提供统一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于关系型数据库的队列。队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短 Web 请求和相应的时间。

队列配置文件存放在 config/queue.php 。每一种队列驱动的配置都可以在该文件中找到,包括数据库,Beanstalkd ,Amazon SQS,Redis,以及同步(本地使用)驱动。其中还包含了一个 null 队列驱动用于那些放弃队列的任务

为什么使用队列?

一般来说使用队列是为了:

异步
重试

也许你还有其他的理由使用队列,但是这应该是最基本的两个原因。

什么情况使用队列?

了解了为什么使用队列,那么一般有这么几类任务使用队列:

耗时比较久的,比如上传一个文件后进行一些格式的转化等。

需要保证送达率的,比如发送短信,因为要调用别人的 api,总会有几率失败,那么为了保证送达,重试就必不可少了。
使用队列的时候一定要想明白一个问题,这个任务到底是不是可以异步,如果因为异步会导致问题,那么就要放弃使用队列。

驱动的必要设置

database.php

在 database.php 配置文件中对 redis 数据库部分进行配置,默认有一个 default 连接,就用这个好了:)
根据这个默认连接中需要的配置项,编辑 .env 配置文件,将其中的 REDIS_HOST、REDIS_PASSWORD、REDIS_PORT 填写成自己服务器中 Redis 的相应值。

queue.php

首先需要去 .env 中配置 QUEUE_DRIVER,因为现在打算用 Redis,所以配置成 redis。

接着配置 queue.php 里 connections 部分的 redis 连接,其中 connection 对应的值就是 database.php 中 redis 的那个 default 连接。

数据库

要使用 database 这个队列驱动的话,你需要创建一个数据表来存储任务。你可以用 queue:table 这个 Artisan

php artisan queue:table

处理失败的任务

有时候你队列中的任务会失败。不要担心,本来事情就不会一帆风顺。

Laravel 内置了一个方便的方式来指定任务重试的最大次数。当任务超出这个重试次数后,它就会被插入到 failed_jobs 数据表里面。要创建 failed_jobs 表的迁移文件,你可以用 queue:failed-table 命令,接着使用 migrate Artisan 命令生成 failed_jobs 表:

php artisan queue:failed-table

命令来创建这个数据表的迁移。当迁移创建好以后,就可以用 migrate 这条命令来创建数据表:

php artisan migrate

执行命令讲解

php artisan queue:work --daemon --quiet --queue=default --delay=3 --sleep=3 --tries=3
--daemon

The queue:work Artisan command includes a --daemon option for forcing the queue worker to continue processing jobs without ever re-booting the framework. This results in a significant reduction of CPU usage when compared to the queue:listen command

总体来说,在 supervisor 中一般要加这个 option,可以节省 CPU 使用。

--quiet

不输出任何内容

--delay=3

一个任务失败后,延迟多长时间后再重试,单位是秒。这个值的设定我个人建议不要太短,因为一个任务失败(比如网络原因),重试时间太短可能会出现连续失败的情况。

--sleep=3

去 Redis 中拿任务的时候,发现没有任务,休息多长时间,单位是秒。这个值的设定要看你的任务是否紧急,如果是那种非常紧急的任务,不能等待太长时间。

--tries=3

定义失败任务最多重试次数。这个值的设定根据任务的重要程度来确定,一般 3 次比较适合。

创建任务

生成任务类

在你的应用程序中,队列的任务类都默认放在 app/Jobs 目录下。如果这个目录不存在,那当你运行 make:job Artisan 命令时目录就会被自动创建。你可以用以下的 Artisan 命令来生成一个新的队列任务:

php artisan make:job Demo

生成的类实现了 Illuminate\Contracts\Queue\ShouldQueue 接口,这意味着这个任务将会被推送到队列中,而不是同步执行。

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Log;

class Demo implements ShouldQueue
{
 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

 public $param;
 /**
 * Create a new job instance.
 *
 * @return void
 */
 public function __construct($param = '')
 {
 $this->param = $param;
 }

 /**
 * Execute the job.
 *
 * @return void
 */
 public function handle()
 {
 Log::info('Hello, '.$this->param);
 }
}

控制器代码

public function queue_demo()
{
 $num = rand(1,999999999);
 // 这个任务将被分发到默认队列...
 DemoJob::dispatch($num);
}

开启队列

php artisan queue:work --queue=default

由于是本地,需要打开监听,当访问到接口时,就会触发队列中的任务

线上的话需要用到supervisor的配置

Supervisor 配置

安装 Supervisor

Supervisor 是一个 Linux 操作系统上的进程监控软件,它会在 queue:listen 或 queue:work 命令发生失败后自动重启它们。在 Ubuntu 安装 Supervisor,可以用以下命令:

sudo apt-get install supervisor

{tip} 如果自己手动配置 Supervisor 听起来有点难以应付,可以考虑使用 Laravel Forge,它能给你的 Laravel 项目自动安装与配置 Supervisor。

配置 Supervisor

Supervisor 的配置文件一般是放在 /etc/supervisor/conf.d 目录下。在这个目录中你可以创建任意数量的配置文件来要求 Supervisor 怎样监控你的进程。例如我们创建一个 laravel-worker.conf 来启动与监控一个 queue:work 进程:

[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
autostart=true
autorestart=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log

这个例子里的 numprocs 命令会要求 Supervisor 运行并监控 8 个 queue:work 进程,并且在它们运行失败后重新启动。当然,你必须更改 command 命令的 queue:work sqs ,以显示你所选择的队列驱动。

启动 Supervisor 当这个配置文件被创建后,你需要更新 Supervisor 的配置,并用以下命令来启动该进程:

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start laravel-worker:*

更多有关 Supervisor 的设置与使用,请参考 Supervisor 官方文档

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
关于访问控制的一首PHP面试题(对属性或方法的访问控制)
Sep 13 PHP
PHP在引号前面添加反斜杠(PHP去除反斜杠)
Sep 28 PHP
php使用exec shell命令注入的方法讲解
Nov 12 PHP
在Mac OS上搭建PHP的Yii框架及相关测试环境
Feb 14 PHP
PHP反射API示例分享
Oct 08 PHP
php中分页及SqlHelper类用法实例
Jan 12 PHP
PHP和MYSQL实现分页导航思路详解
Apr 11 PHP
PHP验证码无法显示的原因及解决办法
Aug 11 PHP
PHP实现的链式队列结构示例
Sep 15 PHP
thinkPHP利用ajax异步上传图片并显示、删除的示例
Sep 26 PHP
使用PHPUnit进行单元测试并生成代码覆盖率报告的方法
Mar 08 PHP
PHP中的自动加载操作实现方法详解
Aug 06 PHP
PHP单文件上传原理及上传函数的封装操作示例
Sep 02 #PHP
PHP实现单文件、多个单文件、多文件上传函数的封装示例
Sep 02 #PHP
PHP 文件上传限制问题
Sep 01 #PHP
laravel框架模板之公共模板、继承、包含实现方法分析
Aug 30 #PHP
php中的钩子理解及应用实例分析
Aug 30 #PHP
Yii框架分页技术实例分析
Aug 30 #PHP
Laravel5.4简单实现app接口Api Token认证方法
Aug 29 #PHP
You might like
PHP模板引擎Smarty的缓存使用总结
2014/04/24 PHP
CodeIgniter启用缓存和清除缓存的方法
2014/06/12 PHP
PHP内置的Math函数效率测试
2014/12/01 PHP
使用PHPWord生成word文档的方法详解
2019/06/06 PHP
javascript实现的listview效果
2007/04/28 Javascript
用Javascript实现锚点(Anchor)间平滑跳转
2009/09/08 Javascript
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
JavaScript 程序编码规范
2010/11/23 Javascript
JS打开新窗口的2种方式
2013/04/18 Javascript
JSON序列化与解析原生JS方法且IE6和chrome测试通过
2013/09/05 Javascript
深入理解javascript中return的作用
2013/12/30 Javascript
javascript实现youku的视频代码自适应宽度
2015/05/25 Javascript
AngularJS 最常用的功能汇总
2016/02/17 Javascript
微信小程序 使用picker封装省市区三级联动实例代码
2016/10/28 Javascript
Angular中$state.go页面跳转并传递参数的方法
2017/05/09 Javascript
Kindeditor单独调用单图上传增加预览功能的实例
2017/07/31 Javascript
JS获取指定月份的天数两种实现方法
2018/06/22 Javascript
浅谈vue中关于checkbox数据绑定v-model指令的个人理解
2018/11/14 Javascript
微信小程序如何调用图片接口API并居中显示
2019/06/29 Javascript
[40:27]完美世界DOTA2联赛PWL S3 PXG vs GXR 第一场 12.19
2020/12/24 DOTA
python ElementTree 基本读操作示例
2009/04/09 Python
Python subprocess模块功能与常见用法实例详解
2018/06/28 Python
Python初学者需要注意的事项小结(python2与python3)
2018/09/26 Python
Django自带的加密算法及加密模块详解
2019/12/03 Python
python为QT程序添加图标的方法详解
2020/03/09 Python
Python 中 sorted 如何自定义比较逻辑
2021/02/02 Python
HTML5实现QQ聊天气泡效果
2017/06/26 HTML / CSS
新学期红领巾广播稿
2014/01/14 职场文书
班组安全员工作职责
2014/02/01 职场文书
2014物价局民主生活会对照检查材料思想汇报
2014/09/24 职场文书
授权委托书怎么写
2014/09/25 职场文书
小学教师学习党的群众路线教育实践活动心得体会
2014/10/31 职场文书
巾帼文明岗事迹材料
2014/12/24 职场文书
检讨书范文1000字
2015/01/28 职场文书
2015年销售部工作总结范文
2015/04/27 职场文书
复活读书笔记
2015/06/29 职场文书