业务需求

本文是以laravel框架来介绍redis队列,具体用法你可以参考http://www.cnblogs.com/lengthuo/p/7277260.html
最近接受一个很简单的东西,(说起来很简单,硬是搞了2天。)我们业务中的一些定时是在晚上执行,但是有的定时必须推送微信消息给用户,为了不影响客户的休息,我们之后想把发去推迟这个任务。
对于我们开发来说,我们只需要知道2件事,入队列和出队列。

入队列

非常简单,我们只需要把数据放到队列中就行了,这里选用redis来作为我们的容器来存储队列,当然你也可以选择用数据库,或者其他的,laraevel支持好多中方式。
redis中用list去存储队列,但是当遇到延迟发送的时候,其实是使用redis的zset(有序的集合列表)来存储的队列。因为有延迟时间吗,我们知道redis的zset的数据结构,有一个value和score ,score是用来排序的,laravel很巧妙的用它来存储发送的时间戳。当然这些其实我们都不需要知道,在laravel框架中,QueueRedis已经封装的非常好了,我们只需要简单的调用

 //方法一 使用内置函数
$job = (new SendWechatMessage($data))->onQueue('queue-name')->delay($delay);
dispatch($job); //方法二 使用门面
//当没有延迟的时候,redis是直接存到list中的
\Queue::push(new SendWechatMessage($data), '', 'queue-name');
//有延迟的时候存入的是zset类型中的
\Queue::later($delay, new SendWechatMessage($data), '', 'redpacket');

在这推荐一个工具
rdm.app 可视化的工具去操作redis,日志中还会有显示对redis操作的日志。很好用,极力推荐。

出队列

laravel中我们只需要简单的启动队列任务就行了,当然laravel文档讲解的更清楚,我就不想说了,我只是简单的提一下几点注意的,和一些原理的东西。

启动队列的方式

queue:work 默认只执行一次队列请求, 当请求执行完成后就终止;
queue:listen 监听队列请求, 只要运行着, 就能一直接受请求, 除非手动终止;
queue:work --daemon 同 listen 一样, 只要运行着, 就能一直接受请求, 不一样的地方是在这个运行模式下, 当新的请求到来的时候, 不重新加载整个框架, 而是直接 fire 动作.
能看出来, queue:work --daemon 是最高级的, 一般推荐使用这个来处理队列监听.
注意: 使用 queue:work --daemon , 当更新代码的时候, 需要停止, 然后重新启动, 这样才能把修改的代码应用上。

原理

首先对存入队列的值进行分析
无延迟队列,直接使list存入,然后在queue:listen 的时候

    public function listen($connection, $queue, $delay, $memory, $timeout = 60)
{
$process = $this->makeProcess($connection, $queue, $delay, $memory, $timeout);
while (true) {//无限循环,所以耗费资源,建议选择使用work命令
$this->runProcess($process, $memory);
}
}

一直从redis list中去取数据。所以一旦有生产者放入,就会很快的被消费之监听。也是非常简单的一种模式
有延迟队列,我只说在laravel中的实现,可能每一种框架都会有不同的实现。
在redis中是由zset来存储延迟队列值得,当有一个延迟队列推送来之后,会存入到redis的zset中,value为要存入的redis中的值,而score为time()+要推迟的时间,所以score存入的是时间戳,laravel框架中在解析的时候会组装一句命令发给redis服务器,
zrangebyscore queues:queue-name:delayed -inf 1504105422
这条命令的意思是:返回小于1504105422时间戳的值,也就是说每一次执行的时候,laravel都是拿当前的时间戳值和redis第一条比较(默认是顺序的,并且第一条是最小的)
说到这是不是豁然开朗,如果不明白可以私聊我,也可以多看看,我相信读完你必有收获。

如果你跟debug的话,就会发现其实laravel包装的所有操作只是来组装数据,最后直接发给redis服务器来处理,然后返回结果。其实就是这么简单。laravel包装的太过于完美,以至于我们什么都不用做。只是简单2行代码就实现了对redis消息队列的操作。

总结

有的时候我们放眼去看,对于这种多种服务交互的时候,原理都是一样的,就比如我们操作mysql,程序肯定不会认识,程序只负责组装sql语句,最后都是会交给mysql服务器来处理,redis也一样,我们只需要组装redis的命令,最后发给redis服务器,他只需要给我们返回结果就可以了。希望本篇文章对你有用。

      路漫漫其修远兮,吾将上下而求索

redis实现消息队列的更多相关文章

  1. Redis 做消息队列

    一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式.利用redis这两种场景的消息队列都能够实现.定义: 生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列, ...

  2. Redis作为消息队列服务场景应用案例

    NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例   一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更 ...

  3. redis resque消息队列

    Resque 目前正在学习使用resque .resque-scheduler来发布异步任务和定时任务,为了方便以后查阅,所以记录一下. resque和resque-scheduler其优点在于功能比 ...

  4. 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能

    springboot+redis实现发布订阅功能,实现redis的消息队列的功能 参考:https://www.cnblogs.com/cx987514451/p/9529611.html 思考一个问 ...

  5. 【Redis】php+redis实现消息队列

    在项目中使用消息队列一般是有如下几个原因: 把瞬间服务器的请求处理换成异步处理,缓解服务器的压力 实现数据顺序排列获取 redis实现消息队列步骤如下: 1).redis函数rpush,lpop 2) ...

  6. Lumen开发:结合Redis实现消息队列(1)

    1.简介 Lumen队列服务为各种不同的后台队列提供了统一的API.队列允许你推迟耗时任务(例如发送邮件)的执行,从而大幅提高web请求速度. 1.1 配置 .env文件的QUEUE_DRIVER选项 ...

  7. Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流

    1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...

  8. sping+redis实现消息队列的乱码问题

    使用spring支持redis实现消息队列,参考官方样例:https://spring.io/guides/gs/messaging-redis/ 实现后在运行过程中发现消费者在接收消息时会出现乱码的 ...

  9. 程序员过关斩将--redis做消息队列,香吗?

    Redis消息队列 在程序员这个圈子打拼了太多年,见过太多的程序员使用redis,其中一部分喜欢把redis做缓存(cache)使用,其中最典型的当属存储用户session,除此之外,把redis作为 ...

  10. NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例

    一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更复杂,可能包含嵌入对象.消息被发送到队列中,“消息队列”是在消息的传输过程中保存消息的容器 ...

随机推荐

  1. 解决ionic中 Action Sheets 在安卓机中的样式

    /** * Action Sheets for Android * -------------------------------------------------- */ .platform-an ...

  2. JSON风格指南

    中文版:https://github.com/darcyliu/google-styleguide/blob/master/JSONStyleGuide.md 英文版:https://google.g ...

  3. Android学习笔记-Button(按钮)

    Button是TextView的子类,所以TextView上很多属性也可以应用到Button 上!我们实际开发中对于Button的,无非是对按钮的几个状态做相应的操作,比如:按钮按下的时候 用一种颜色 ...

  4. Linux下软件的卸载

    一.rpm -q -a 查看所安的全部软件 二.#rpm -e [package name]  卸载想要卸载的软件  

  5. 25. leetcode 217. Contains Duplicate

    217. Contains Duplicate Given an array of integers, find if the array contains any duplicates. Your ...

  6. PAT (Basic Level) Practise (中文) 1023. 组个最小数 (20)

    1023. 组个最小数 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 给定数字0-9各若干个.你可以以 ...

  7. BFS:noi6044鸣人与佐助

    PS:一道XX到我心态崩溃的好(傻逼)题. 先粘题目: 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到,只不过 ...

  8. Selenium对于对话框alert,confirm,prompt的处理

    html 源码: <html>                  <head>                      <title>Alert</titl ...

  9. iOS获取用户设备崩溃日志并分析

    项目最近发布,部分用户在内侧使用,正好遇到一些问题,由于用户在其他城市,所以对于用户设备产生的崩溃日志,不好直接拿设备连接电脑. 对于这种情况,我们可以这样: 1.引导用户开启iOS设备设置-> ...

  10. python基础===Python 代码优化常见技巧

    Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化.扩展以及文档相关的事情通常需要消耗 8 ...