前言


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队列(一)的更多相关文章

  1. laravel中redis队列的使用

    一.配置文件 首先我们需要在配置文件中配置默认队列驱动为Redis,队列配置文件是config/queue.php: return [ 'default' => env('QUEUE_DRIVE ...

  2. [原创]Laravel 基于redis队列的解析

    目录 参考链接 本文环境 为什么使用队列 Laravel 中的队列 分发任务 任务队列 Worker Last-Modified: 2019年5月10日11:44:18 参考链接 使用 Laravel ...

  3. laravel使用redis队列实践(只需6步,超详细,超简单)

    1.配置使用redis队列 在.env文件找到QUEUE_DRIVER=sync改成QUEUE_DRIVER=redis redis配置一般不用改如果有密码改.env文件的REDIS_PASSWORD ...

  4. Laravel中的队列处理

    Laravel中的队列处理 队列介绍 为什么要有消息队?这里先对其进行一个简单的介绍,方便还不了解的同学理解.在面向对象里,有一个很简单的概念--消息传递,而消息队列就可以在它上面扩展一下,把它说的更 ...

  5. netty实现消息中心(一)思路整理

    一.需求 需要实现直播间的以下功能: 群发消息(文本.图片.推荐商品) 点对点私发消息(文本.图片.推荐商品) 单个用户禁言 全体用户禁言 撤回消息 聊天记录持久化 二.技术实现 服务端消息中心采用n ...

  6. 我心中的核心组件~MSMQ与Redis队列

    回到目录 这个文章其实是我心中的核心组件的第七回,确实在时间上有些滞后了,但内容并不滞后!本文MSMQ只是个引题,我确实不太想说它,它是微软自己集成的一套消息队列,寄宿在Window服务里,稳定性十在 ...

  7. c#之Redis队列在邮件提醒中的应用

    场景 有这样一个场景,一个邮件提醒的windows服务,获取所有开启邮件提醒的用户,循环获取这些用户的邮件,发送一条服务号消息.但问题来了,用户比较少的情况下,轮询一遍时间还能忍受,如果用户多了,那用 ...

  8. RabbitMQ、Memcache、Redis(队列、缓存)

    RabbitMQ 一.解释 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消 ...

  9. redis队列的实现

    redis中文官网:http://www.redis.cn/ 关于redis队列的实现方式有两种: 1.生产者消费者模式. 2.发布者订阅者模式. 详解: 1.生产者消费者模式. 普通版本: 比如一个 ...

随机推荐

  1. poll(2) 源码分析

    poll(2) poll(2) 系统调用的功能和 select(2) 类似:等待一个文件集合中的文件描述符就绪进行I/O操作. 使用 实现 select(2) 的局限性: 关注的文件描述符集合大小最大 ...

  2. 【CSS】width和height计算

    width:calc(100% - 20px); width:-webkit-calc(100% - 20px);//chrome width:-moz-calc(100% - 20px);//fir ...

  3. 我又不是你的谁--java instanceof操作符用法揭秘

    背景故事 <曾经最美>是朱铭捷演唱的一首歌曲,由陈佳明填词,叶良俊谱曲,是电视剧<水晶之恋>的主题曲.歌曲时长4分28秒. 歌曲歌词: 看不穿你的眼睛 藏有多少悲和喜 像冰雪细 ...

  4. 从一道ctf看php反序列化漏洞的应用场景

    目录 0x00 first 前几天joomla爆出个反序列化漏洞,原因是因为对序列化后的字符进行过滤,导致用户可控字符溢出,从而控制序列化内容,配合对象注入导致RCE.刚好今天刷CTF题时遇到了一个类 ...

  5. 超炫酷的 IntelliJ IDEA 插件(一)

    工善其事必先利器 打开setting文件选择Plugins选项 Ctrl + Alt + S File -> Setting 我的idea是最新版本2019.02 有的和别人界面可能不一样 主界 ...

  6. Java学习笔记之封装与继承

    封装 1,将属性定义为私有的(private)   不能通过  对象名.属性  来直接访问,但是可以通过方法来间接的访问, 2,封装的意义:公有属性可以被随意修改,并且不能被程序察觉.封装后,别人通过 ...

  7. springboot 快速开发的定制补充

    增强 SpringBoot 快速开发工具 项目地址:https://gitee.com/sanri/web-ui 优点:这是一个 web 通用配置的组件,即插即用,可用于新项目或私活.是对 Sprin ...

  8. css 文字间距

    letter-spacing :  字与字之间的距离 text-indent : 行的抬头间距 line-height : 行高度

  9. PHP array_change_key_case

    (PHP 4 >= 4.2.0, PHP 5, PHP 7) 1.函数的作用 : 改变数组所有键值的大小写: 2.参数: 1)array : 应用的数组: 2)case  : 指定转换为大写或者 ...

  10. JS中==运行机制

    1. 判断两边是否有NaN,如果有则一律返回false 2.判断两边是否含有布尔值,如果有的话则将true转化为1,false转化为0. 3.遇到null或者undefined,则不会进行类型转换,它 ...