业务需求

本文是以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. Java工程师的终极书单

    本份Java工程师的终极书单只在专业的Java技术博客–天天编码上发布,没有授权任何网站与个人转载. 坚持阅读好书是学习Java技术的好方式.但是,市面上与Java技术相关的书籍可谓数不胜数,如何从这 ...

  2. [noip 2015]运输计划 [LCA][树链剖分]

    用了luogu上的题目描述 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的 ...

  3. 【CSS3】块级元素与行内元素的区别

    一.行内元素与块级函数的三个区别 行内元素的特点: 和其他元素都在一行上: 高,行高及外边距和内边距部分可改变: 宽度只与内容有关: 行内元素只能容纳文本或者其他行内元素. 行内元素设置width无效 ...

  4. ML(2)--感知机

    案例银行办信用卡--获得感知机 我们到银行办信用卡时,银行并不是直接就给你办卡的,而是会根据你的一些个人信息.消费信息.个人信誉等指标综合考虑后,才会决定是否给你办卡(不像现在银行办信用卡有点随意). ...

  5. (MVC)javaBaen+jsp+servlet对数据的操作

    运用MVC对数据进行一些简单的处理,基本实现数据的增删改查,达到前端和后台的数据之间的交互. 1.开始界面 <%@page import="com.zdsofe.work.Studen ...

  6. 使用maven搭建环境

    今天第一次用maven创建springmvc工程,下载配置都很成功,但用命令行创建项目时遇到一些问题: 1.命令行显示命令不为内部或外部命令: 解决方法:使用管理员模式打开命令行 2. 显示到如下图所 ...

  7. 大数据算法->推荐系统常用算法之基于内容的推荐系统算法

    港真,自己一直非常希望做算法工程师,所以自己现在开始对现在常用的大数据算法进行不断地学习,今天了解到的算法,就是我们生活中无处不在的推荐系统算法. 其实,向别人推荐商品是一个很常见的现象,比如我用了一 ...

  8. 一个最最简易的RPC框架雏形---转载自梁飞的博客

    查阅RPC与HTTP区别的时候, 无意间发现一篇博客,内容是一个简易的RPC服务框架, 仔细一看, 不得了,博主竟然就是阿里dubbo的作者. 原文链接在此: http://javatar.iteye ...

  9. Spark No FileSystem for scheme file 解决方法

    在给代码带包成jar后,放到环境中运行出现如下错误: Exception in thread "main" java.io.IOException: No FileSystem f ...

  10. C++标准库string

    C++标准库string 定义和初始化 string s1 默认初始化,s1是一个空串 string s2(s1) s2是s1的副本 string s2 = s1 等价于s2(s1),s2是s1的副本 ...