Laravel入坑指南(11)——列队
很高兴,我们来到了Laravel入坑指南的第11篇。这一系列的文章已经接近尾声了,在这一节里面,我们一起讨论列队的用法。
列队,顾名思义,将需要处理的任务一个一个排好队,等待处理程序来处理。这机的列队机制,适用于需要异步处理的任务。
所以在这里,我们首先需要关注三个问题:谁来投递任务?将任务投递到哪里?谁来处理任务?
1、谁来投递任务?
在Laravel里,任务的投递和处理,都是由JOB类负责的。而且哪个JOB类投递的任务,就由那个JOB类进行处理(划重点)。首先,执行以下命令,就可以创建自己的JOB类:
php artisan make:job ProcessMyJob
这时,就会创建出/app/Jobs/ProcessMyJob.php。在这个类中,有一个构造函数,以及一个handle参数。构造函数的参数,就是分发任务时指定的参数,在获取任务实例化JOB时,就将列队中的任务参数传递进来;handle函数则是处理函数。
有了个这JOB类之后,我们可以在我们需要投递任务的地方(比如某个Controller里)进行投递:
//投递到默认列队,默认列队队名由配置文件决定,一般叫作default
ProcessMyJob::dispatch("参数"); //投递到名字为default2的列队
ProcessMyJob::dispatch("参数")->onQueue("myqueue");
现在问题来了,默认列队和名为myqueue的列队分别在哪里呢?
2、将任务投递到哪里?
关于这个问题,取决于配置文件/config/queue.php。在这个配置文件中,我们需要关注两个配置项:default和connections。
2.1 connections
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('AWS_REGION', 'us-east-1'),
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
],
这个配置项,让Laravel可以用同步、数据库、beanstalkd、亚马逊sql以及redis的方法来保存列队数据。当然,博主个人建议用redis来进行存储,所以下面所有的示例也会以redis作为例子进行讨论。我们在第6节中,已经配置完redis。如果还不明白的同学,请返回查看第6节。
根据上面所示connections配置项中,我们只需在/.evn文件中添加一个配置项:
REDIS_QUEUE=default
这一项就是指定上面所说的默认列队名字。当任务投递时没有指定名字,就会投递到这个名下的列队中。
2.2 default
这一项则是指定了名为default的列队,用哪种方式保存列队数据。因为上面的例子中,我们要把任务投递到名字为myqueue的列队中,所以我们还需要一个名为myqueue的列队。所以我们的配置如下:

在/.env配置文件中QUEUE_CONNECTION的值为redis:
QUEUE_CONNECTION=redis
到这里,我们知道任务由谁投递的,任务保存在哪里。那么在指定的地方投递完任务后,由谁调用JOB的handle函数,对任务进行处理呢?就是我们接下来关注的重点。
3、谁来处理任务?
在这里,我们需要操作系统长驻进程,一直监视着列队是否有任务要处理。所以我们还是离不开php的命令行。我们可以用以下方式启动监视进程:
#启动对所有列队的监听
php artisan queue:work #启动对default和myqueue的监听,default列队的优先级会高于myqueue的优先级
php artisan queue:work --queue=default,myqueue #在redis连接上启动对email列队的监听
#这种情况就不需要在配置文件中写email列队的配置项
php artisan queue:work redis --queue=email #列队清空后就退出
php artisan queue:work --stop-when-empty #启动两个监听进程,两个列队没有优先级关系
php artisan queue:work --queue=default
php artisan queue:work --queue=myqueue
被监听的列队,一旦有任务存在,监听进程就会实例化对应的JOB类,并调用handle函数进行处理。
4、万一监听进程挂了,怎么办?
为了解决这个问题,官方文档介绍了可以用Linux下的supervisor进行进程守护。现在让我们简单探讨
在CentOS下安装supervisor只需要执行:
yum install supervisor
安装完成后在就会创建出/etc/supervisord.conf配置文件和/etc/supervisord.d目录。其中,配置文件中有以下配置项:
[include]
files = supervisord.d/*.ini
所有的进程守护配置文件都存放在/etc/supervisord.d路径中。
安装完成后,我们需要创建启动脚本/etc/init.d/supervisor
#!/bin/sh # Source init functions
. /etc/rc.d/init.d/functions prog="supervisord" prefix="/usr/local"
exec_prefix="${prefix}"
prog_bin="${exec_prefix}/bin/supervisord"
PIDFILE="/var/run/$prog.pid" start()
{
echo -n $"Starting $prog: "
daemon $prog_bin -c /etc/supervisord.conf --pidfile $PIDFILE
[ -f $PIDFILE ] && success $"$prog startup" || failure $"$prog startup"
echo
} stop()
{
echo -n $"Shutting down $prog: "
[ -f $PIDFILE ] && killproc $prog || success $"$prog shutdown"
echo
} case "$1" in start)
start
;; stop)
stop
;; status)
status $prog
;; restart)
stop
start
;; *)
echo "Usage: $0 {start|stop|restart|status}"
;; esac
接下来,让我们进行一下测试,看看supervisor是否有效。创建一个配置文件:
/etc/supervisord.d/myqueue.ini
[program:myqueue]
process_name=%(program_name)s_%(process_num)02d
command=php /www/wwwroot/default/artisan queue:work
autostart=true
autorestart=true
numprocs=4
redirect_stderr=true
stdout_logfile=/tmp/test.out.log
创建完成后,执行
/etc/init.d/supervisor restart
会发现我们的列队监视进程已经启动,并且在我们kill掉进程时会自动重启。
到这里,我们列队的话题大功告成。
最后我们关注上一节遗留下的最后一个问题,关于事件Listener处理。如里我们需要以列队进行事件的处理,我们只需要让侦听器实现ShouldQueue接口即可:
<?php
namespace App\Listeners; use Illuminate\Contracts\Queue\ShouldQueue; class MyListener implements ShouldQueue
{
/**
* 任务将被推送到的连接名称.
*
* @var string|null
*/
public $connection = 'redis'; /**
* 任务将被推送到的列队名称.
*
* @var string|null
*/
public $queue = 'queue_name'; /**
* 任务被处理之前的延迟时间(秒)
*
* @var int
*/
public $delay = 60;
}
--------------------------- 我是可爱的分割线 ----------------------------
最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同学点击链接,联系我吧。
Laravel入坑指南(11)——列队的更多相关文章
- electron入坑指南
electron入坑指南 简介 electron 实际集成chrome浏览器和node环境, 运行你写的网页 app 基本目录结构 index.html 名称可以不是index, 这个文件与普通网页的 ...
- C语言入坑指南-被遗忘的初始化
前言 什么是初始化?为什么要初始化?静态变量和局部变量的初始化又有什么区别?实际应用中应该怎么做?本文将一一回答这些问题. 什么是初始化 初始化指的是对数据对象或者变量赋予初始值.例如: int va ...
- Elasticsearch入坑指南之RESTful API
Elasticsearch入坑指南之RESTful API Tags:Elasticsearch ES为开发者提供了非常丰富的基于Http协议的Rest API,通过简单的Rest请求,就可以实现非常 ...
- ElasticSearch入坑指南之概述及安装
---恢复内容开始--- ElasticSearch入坑指南之概述及安装 了解ElasticSearch ElasticSearch(简称ES)基于Lucene的分布式全文检索引擎.使用ES可以实现近 ...
- eclipse中导入外部包却无法查看对应源码或Javadoc的入坑指南
eclipse中导入外部包却无法查看对应源码或Javadoc的 入坑指南 出现这个错误的原因是,你虽然导入了.jar包,但没有配置对应的Javadoc或源码路径,所以在编辑器中无法查看源 码和对应AP ...
- Rust入坑指南:核心概念
如果说前面的坑我们一直在用小铲子挖的话,那么今天的坑就是用挖掘机挖的. 今天要介绍的是Rust的一个核心概念:Ownership.全文将分为什么是Ownership以及Ownership的传递类型两部 ...
- Rust入坑指南:鳞次栉比
很久没有挖Rust的坑啦,今天来挖一些排列整齐的坑.没错,就是要介绍一些集合类型的数据类型."鳞次栉比"这个标题是不是显得很有文化? 在Rust入坑指南:常规套路一文中我们已经介绍 ...
- Rust入坑指南:亡羊补牢
如果你已经开始学习Rust,相信你已经体会过Rust编译器的强大.它可以帮助你避免程序中的大部分错误,但是编译器也不是万能的,如果程序写的不恰当,还是会发生错误,让程序崩溃.所以今天我们就来聊一聊Ru ...
- Rust入坑指南:朝生暮死
今天想和大家一起把我们之前挖的坑再刨深一些.在Java中,一个对象能存活多久全靠JVM来决定,程序员并不需要去关心对象的生命周期,但是在Rust中就大不相同,一个对象从生到死我们都需要掌握的很清楚. ...
- Rust入坑指南:齐头并进(上)
我们知道,如今CPU的计算能力已经非常强大,其速度比内存要高出许多个数量级.为了充分利用CPU资源,多数编程语言都提供了并发编程的能力,Rust也不例外. 聊到并发,就离不开多进程和多线程这两个概念. ...
随机推荐
- 云服务器搭建自己的GitServer!
云服务器搭建自己的GitServer! 如果你有一台云服务器并想在上面搭建自己的 Git 服务器,你可以使用 Git 自带的 git-shell ,也可以使用像 Gitea.GitLab.Gogs 这 ...
- Go-错误栈信息
Go中错误栈信息 .\main.go:22:2: number1 declared but not used .\main.go 错误发生的文件 22:2 文件的22行第2列 number1 decl ...
- [转帖]tgz 安装clickhouse
一.什么是clickhouse ClickHouse是开源的列式存储数据库(DBMS),主要用于在线处理查询(OLAP),能够使用SQL查询实时生成数据分析报告. 下面介绍下安装clickhouse. ...
- [转帖]s3fs把 s3-like 对象存储挂载到本地
s3fs把 s3-like 对象存储挂载到本地 s3fs把 s3-like 对象存储挂载到本地 s3fs-fuse 是一个采用 c++ 开发的开源应用,它的作用是可以将 AWS S3 以及兼容 S3 ...
- [转帖]看看 Jmeter 是如何玩转 redis 数据库的
柠檬小欧 2021-08-31 20:06420 Jmeter 作为当前非常受欢迎的接口测试和性能测试的工具,在企业中得到非常广泛的使用,而 Redis 作为缓存数据库,也在企业中得到普遍使用,那如何 ...
- [转帖]VMware vCenter证书过期解决方法
https://www.yii666.com/blog/395521.html vCenter证书过期解决方法 目录 1 概述 2 详细操作步骤 2.1 检查关键的STS证书是否过期并修复 2.2 检 ...
- vue中父传子props的使用
第一种 传递一个数组 props:["cont"] 第二种 传递一个对象 props:{ uploadOption:{ type:Object, 参数类型必须是一个对象 requi ...
- VictoriaMetrics 1.84.0发布
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 11.25日,valyala大神发布了VictoriaMe ...
- TienChin 活动管理-修改活动接口
前端 activity.js 直接替换现有的,最求速度了,后面在详细一个个记录,不在过多解释了. import request from '@/utils/request' /** * 查询活动列表 ...
- NLP国内外大模型汇总列表[文心一言、智谱、百川、星火、通义千问、盘古等等]
NLP国内外大模型汇总列表[文心一言.智谱.百川.星火.通义千问.盘古等等] 中国大模型列表大全,全面收集有明确来源的大模型情况,包括机构.来源信息和分类等,随时更新. Awesome family ...