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下使用无限生命期Session的方法
Mar 16 PHP
PHP读取txt文件的内容并赋值给数组的代码
Nov 03 PHP
php分页思路以及在ZF中的使用
May 30 PHP
PHP自动生成后台导航网址的最佳方法
Aug 27 PHP
PHP自定session保存路径及删除、注销与写入的方法
Nov 18 PHP
php实现session自定义会话处理器的方法
Jan 27 PHP
android上传图片到PHP的过程详解
Aug 03 PHP
解析PHP之提取多维数组指定列的方法
Jan 03 PHP
关于php支持的协议与封装协议总结(推荐)
Nov 17 PHP
php无限级分类实现评论及回复功能
Feb 18 PHP
PHP文件上传小程序 适合初学者学习!
May 23 PHP
php设计模式之抽象工厂模式分析【星际争霸游戏案例】
Jan 23 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
先进的自动咖啡技术,真的可以取代咖啡师吗?
2021/03/06 冲泡冲煮
php通过文件头判断格式的方法
2016/05/28 PHP
JavaScript 编程引入命名空间的方法
2007/06/29 Javascript
Javascript new Date().valueOf()的作用与时间戳由来详解
2013/04/24 Javascript
javascript中为某个元素指定事件的三种方式
2014/08/07 Javascript
使用RequireJS优化JavaScript引用代码的方法
2015/07/01 Javascript
JS+CSS实现类似QQ好友及黑名单效果的树型菜单
2015/09/22 Javascript
jQuery选择器用法实例详解
2015/12/17 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
js中获取jsp表单中radio类型的值简单实例
2016/08/15 Javascript
基于Javascript实现的不重复ID的生成器
2016/12/25 Javascript
React Native 搭建开发环境的方法步骤
2017/10/30 Javascript
自定义PC微信扫码登录样式写法
2017/12/12 Javascript
Vue2.0系列之过滤器的使用
2018/03/01 Javascript
微信小程序实现人脸检测功能
2018/05/25 Javascript
vue实现学生录入系统之添加删除功能
2018/07/11 Javascript
layui radio性别单选框赋值方法
2018/08/15 Javascript
微信小程序实现顶部导航特效
2019/01/28 Javascript
vscode配置vue下的es6规范自动格式化详解
2019/03/20 Javascript
vue实现图片预览组件封装与使用
2019/07/13 Javascript
JavaScript代码异常监控实现过程详解
2020/02/17 Javascript
Python enumerate遍历数组示例应用
2008/09/06 Python
Python字典简介以及用法详解
2016/11/15 Python
Python编程之gui程序实现简单文件浏览器代码
2017/12/08 Python
Python3实现的字典遍历操作详解
2018/04/18 Python
对python中Json与object转化的方法详解
2018/12/31 Python
Laravel框架表单验证格式化输出的方法
2019/09/25 Python
python中利用matplotlib读取灰度图的例子
2019/12/07 Python
MAC Cosmetics巴西官方网站:M·A·C彩妆
2019/04/18 全球购物
冬季施工防火方案
2014/05/17 职场文书
建筑工程技术专业求职信
2014/07/16 职场文书
甲午大海战观后感
2015/06/02 职场文书
浅谈Nginx 中的两种限流方式
2021/03/31 Servers
基于CSS3画一个iPhone
2021/04/21 HTML / CSS
利用python调用摄像头的实例分析
2021/06/07 Python
python周期任务调度工具Schedule使用详解
2021/11/23 Python