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 输出双引号&quot;与单引号'的方法
May 09 PHP
mysql,mysqli,PDO的各自不同介绍
Sep 19 PHP
深入分析php中接口与抽象类的区别
Jun 08 PHP
PHP解析RSS的方法
Mar 05 PHP
CI框架中$this-&gt;load-&gt;library()用法分析
May 18 PHP
PHP图片添加水印功能示例小结
Oct 03 PHP
Laravel中间件实现原理详解
Oct 09 PHP
关于PHP转换超过2038年日期出错的问题解决
Jun 28 PHP
PHP 返回数组后处理方法(开户成功后弹窗提示)
Jul 03 PHP
PHP分页显示的方法分析【附PHP通用分页类】
May 10 PHP
PHP开发实现快递查询功能详解
Apr 08 PHP
php连接mysql数据库最简单的实现方法
Sep 24 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
星际争霸兵种名称对照表
2020/03/04 星际争霸
openflashchart 2.0 简单案例php版
2012/05/21 PHP
PHP5多态性与动态绑定介绍
2015/04/03 PHP
CI框架表单验证实例详解
2016/11/21 PHP
使用PHPStorm+XDebug搭建单步调试环境
2017/11/19 PHP
JQuery 前台切换网站的样式实现
2009/06/22 Javascript
jQuery 美元符冲突的解决方法
2010/03/28 Javascript
ExtJS 设置级联菜单的默认值
2010/06/13 Javascript
JavaScript高级程序设计 读书笔记之八 Function类及闭包
2012/02/27 Javascript
javascript中的toFixed固定小数位数 简单实例分享
2013/07/12 Javascript
jQuery中操控hidden、disable等无值属性的方法
2014/01/06 Javascript
IE6-IE9中tbody的innerHTML不能赋值的解决方法
2014/09/26 Javascript
浅谈JavaScript中的字符编码转换问题
2015/07/07 Javascript
对于jQuery性能的一些优化建议
2015/08/13 Javascript
基于JavaScript短信验证码如何实现
2016/01/24 Javascript
详解ECMAScript6入门--Class对象
2017/04/27 Javascript
使用live-server快速搭建本地服务器+自动刷新的方法
2018/03/09 Javascript
微信小程序实现顶部下拉菜单栏
2018/11/04 Javascript
详解Vue中组件的缓存
2019/04/20 Javascript
基于vue的video播放器的实现示例
2021/02/19 Vue.js
Python探索之创建二叉树
2017/10/25 Python
jupyter notebook引用from pyecharts.charts import Bar运行报错
2020/04/23 Python
Python图像处理实现两幅图像合成一幅图像的方法【测试可用】
2019/01/04 Python
python给图像加上mask,并提取mask区域实例
2020/01/19 Python
Python基础教程(一)——Windows搭建开发Python开发环境
2020/07/20 Python
python爬虫数据保存到mongoDB的实例方法
2020/07/28 Python
python lambda的使用详解
2021/02/26 Python
Gerry Weber德国官网:优质女性时装,德国最大的时装公司之一
2019/11/02 全球购物
捷克购买家具网站:JENA nábytek
2020/03/19 全球购物
String是最基本的数据类型吗?
2013/06/13 面试题
外科实习自我鉴定
2013/10/06 职场文书
计算机科学系职业生涯规划书
2014/03/08 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
2015年车间管理工作总结
2015/07/23 职场文书
旅游安全责任协议书
2016/03/22 职场文书
Python基础之操作MySQL数据库
2021/05/06 Python