消息中心 - Laravel的Redis队列(一)
前言
Laravel的队列可以用在轻量级的队列需求中。比如我们系统中的短信、邮件等功能,这些功能有一些普遍的特征,异步、重试、并发控制等。Laravel现在主要支持的队列服务有Null、Sync、Database、Redis、Beanstalkd、Sqs。
在我们的项目中(消息中心、人事)用的主要是redis,接下来我会介绍下队列基于redis驱动的运行机制。
背景知识
Laravel启动后,加载config/app.php的providers数组中的服务提供者 QueueServiceProvider,在队列服务提供者中,已经注册了一系列相关服务。

在.env配置文件中,我们设置了QUEUE_DRIVER为redis,系统启动后会自动生成Redis连接,同时注册了Work消费者,队列监听器以及错误服务。在queue.php和database.php配置中都默认了相关的redis设置。
任务调度
调度如下:

laravel 的队列服务由两个进程控制,一个是事件生产者(黑线),一个是事件消费者(黄线)。
有三个队列,主队列 queues:default(下面default代替),延时队列 queues:default:delayed(下面delayed代替),待处理队列 queues:default:reserved(下面reserved代替)。所有的队列事件都由事件消费者去消费主队列中的事件。(队列名称default在queue.php中被定义)
1. 事件触发:dispatch(new Event());
事件触发后,dispatch判断Event是否继承队列类,是,将事件分发到队列执行流程中。队列执行流程会根据Event的延时属性判断,否,将Event放到即时处理queues:default 队列中,是,将Event放入延时 queues:default:delayed 队列中。
2. 消费:php artisan queue:work
图中A、B、C、D为消费者进程依次执行步骤,淡黄色背景的代码备注都为对队列的操作命令(predis 实现redis api),每个备注里面对事件的操作要么一起成功,要么一起失败(Lua脚本)。
3. A: 对delayed、default队列操作
A1:取出小于当前时间的(时间戳)所有Event,赋给val,删除delayed队列中0到val.length长度的Event(redis的有序集合有一个分数,有序集合根据这个分数从小到大排序,这里的时间戳就是分数)。
A2:将上面获取的Event,放入到主队列 default。
4. B: 对reserved、default队列操作
B1:取出小于当前时间的所有Event,赋给val,删除reserved队列中0到val长度的Event。
B2:将上面获取的Event,放入到主队列 default。
5. C: 对default、reserved队列操作
C1:取出主队列中的所有Event。
C2:将Event放入reserved,且记录Event的执行次数(保留Event,由D执行后,根据Event执行结果处理这些Event)。
6. D: 处理Event(由C步骤得到的Event,交给D)
根据得到的Event依次执行(也就是通知监听这个Event的所有监听者),同时删除reserved队列的相对应的Event(无论执行失败还是成功),如果执行失败会将任务放入reserved队列中,执行时间为1540097000(1540096910 + 90,90为设置的延时时间),以便下次执行。
结尾
以上就是Laravel队列所有的执行流程,当然里面包括执行失败的错误处理、如何通知监听者等细节都没讲,大家可以自行分析代码理解。
消息中心 - Laravel的Redis队列(一)的更多相关文章
- laravel中redis队列的使用
一.配置文件 首先我们需要在配置文件中配置默认队列驱动为Redis,队列配置文件是config/queue.php: return [ 'default' => env('QUEUE_DRIVE ...
- [原创]Laravel 基于redis队列的解析
目录 参考链接 本文环境 为什么使用队列 Laravel 中的队列 分发任务 任务队列 Worker Last-Modified: 2019年5月10日11:44:18 参考链接 使用 Laravel ...
- laravel使用redis队列实践(只需6步,超详细,超简单)
1.配置使用redis队列 在.env文件找到QUEUE_DRIVER=sync改成QUEUE_DRIVER=redis redis配置一般不用改如果有密码改.env文件的REDIS_PASSWORD ...
- Laravel中的队列处理
Laravel中的队列处理 队列介绍 为什么要有消息队?这里先对其进行一个简单的介绍,方便还不了解的同学理解.在面向对象里,有一个很简单的概念--消息传递,而消息队列就可以在它上面扩展一下,把它说的更 ...
- netty实现消息中心(一)思路整理
一.需求 需要实现直播间的以下功能: 群发消息(文本.图片.推荐商品) 点对点私发消息(文本.图片.推荐商品) 单个用户禁言 全体用户禁言 撤回消息 聊天记录持久化 二.技术实现 服务端消息中心采用n ...
- 我心中的核心组件~MSMQ与Redis队列
回到目录 这个文章其实是我心中的核心组件的第七回,确实在时间上有些滞后了,但内容并不滞后!本文MSMQ只是个引题,我确实不太想说它,它是微软自己集成的一套消息队列,寄宿在Window服务里,稳定性十在 ...
- c#之Redis队列在邮件提醒中的应用
场景 有这样一个场景,一个邮件提醒的windows服务,获取所有开启邮件提醒的用户,循环获取这些用户的邮件,发送一条服务号消息.但问题来了,用户比较少的情况下,轮询一遍时间还能忍受,如果用户多了,那用 ...
- RabbitMQ、Memcache、Redis(队列、缓存)
RabbitMQ 一.解释 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消 ...
- redis队列的实现
redis中文官网:http://www.redis.cn/ 关于redis队列的实现方式有两种: 1.生产者消费者模式. 2.发布者订阅者模式. 详解: 1.生产者消费者模式. 普通版本: 比如一个 ...
随机推荐
- 【SQL】sql查询同一字段相同属性列的值合计
select type,sum(value) as valueSum from t group by type
- 版本控制之Git小结
一.版本控制 1.1 什么是版本控制 版本控制是一种记录一个或若干个文件内容变化,以便将来查阅特定版本修订情况的系统.可以对任何类型的文件进行版本控制. 1.2 为什么需要版本控制 有了版本控制就可以 ...
- C语言-查找一个元素在数组中的位置
#include<stdio.h> #include <stdlib.h> #include <time.h> int search(int key, int a[ ...
- 基于Prometheus和Grafana的监控平台 - 环境搭建
相关概念 微服务中的监控分根据作用领域分为三大类,Logging,Tracing,Metrics. Logging - 用于记录离散的事件.例如,应用程序的调试信息或错误信息.它是我们诊断问题的依据. ...
- JDBC-第1篇-基础
话不多说,直接开撸代码. 1.首先自己的环境使用的是maven项目+idea工具+mysql8.0.18 (使用maven项目的好处就是方便,不用手动导入相关的驱动包,在pom.xml配置即可) 2. ...
- WPF使用border画框
以前的界面中使用的框大都是由美工做好的,但是这样就遇到几个问题: 框只是换一个颜色,就需要多做出一张图,资源包中也要多一个图片资源: 文字的数量会改变,用一张固定的图进行拉伸,边角处会变得越来越不尽如 ...
- 【RabbitMQ 实战指南】一 过期时间TTL
RabbitMQ 可以对消息和队列设置过期时间(TTL) 1.设置消息的TTL 目前有两种方式可以设置消息的TTL 第一种方式是通过队列属性设置,队列中所有消息都有相同的过期时间 第二种方式是对消息本 ...
- 第三方软件 Serv-u提权
Serv-U FTP Server,是一种被广泛运用的FTP服务器端软件,支持3x/9x/ME/NT/2K等全Windows系列.可以设定多个FTP服务器.限定登录用户的权限.登录主目录及空间大小等 ...
- oracle计算两个时间的差值(XX天XX时XX分XX秒)
在工作中需要计算两个时间的差值,结束时间 - 开始时间,又不想在js里写function,也不想在java里去计算,干脆就在数据库做了一个函数来计算两个时间的差值.格式为XX天XX时XX分XX秒: 上 ...
- C/C++语言误区void main( )
很多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的.C/C++ 中从来没有定义过void main( ) .C++ 之父 Bjarne Stroustrup 在他的主页上的 ...