redis实现消息队列
业务需求
本文是以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实现消息队列的更多相关文章
- Redis 做消息队列
一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式.利用redis这两种场景的消息队列都能够实现.定义: 生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列, ...
- Redis作为消息队列服务场景应用案例
NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例 一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更 ...
- redis resque消息队列
Resque 目前正在学习使用resque .resque-scheduler来发布异步任务和定时任务,为了方便以后查阅,所以记录一下. resque和resque-scheduler其优点在于功能比 ...
- 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能
springboot+redis实现发布订阅功能,实现redis的消息队列的功能 参考:https://www.cnblogs.com/cx987514451/p/9529611.html 思考一个问 ...
- 【Redis】php+redis实现消息队列
在项目中使用消息队列一般是有如下几个原因: 把瞬间服务器的请求处理换成异步处理,缓解服务器的压力 实现数据顺序排列获取 redis实现消息队列步骤如下: 1).redis函数rpush,lpop 2) ...
- Lumen开发:结合Redis实现消息队列(1)
1.简介 Lumen队列服务为各种不同的后台队列提供了统一的API.队列允许你推迟耗时任务(例如发送邮件)的执行,从而大幅提高web请求速度. 1.1 配置 .env文件的QUEUE_DRIVER选项 ...
- Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流
1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...
- sping+redis实现消息队列的乱码问题
使用spring支持redis实现消息队列,参考官方样例:https://spring.io/guides/gs/messaging-redis/ 实现后在运行过程中发现消费者在接收消息时会出现乱码的 ...
- 程序员过关斩将--redis做消息队列,香吗?
Redis消息队列 在程序员这个圈子打拼了太多年,见过太多的程序员使用redis,其中一部分喜欢把redis做缓存(cache)使用,其中最典型的当属存储用户session,除此之外,把redis作为 ...
- NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例
一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更复杂,可能包含嵌入对象.消息被发送到队列中,“消息队列”是在消息的传输过程中保存消息的容器 ...
随机推荐
- 简单的小程序实现ATM机操作
简单的小程序实现ATM机操作 代码如下: package Day06; import java.util.Scanner; public class TestAccount { public stat ...
- 【PHP】linux+php5.1.6+mysql5.0.2+apache2.0.55安装配置说明(转)
linux+php5.1.6+mysql5.0.2+apache2.0.55安装配置说明:一.mysql5.0.2的安装配置过程及说明:1. #tar -zvxf mysql-5.0.2-alpha. ...
- python函数(4):递归函数及二分查找算法
人理解循环,神理解递归! 一.递归的定义 def story(): s = """ 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? ""& ...
- 单双引号的区别,defined容易疏忽的小地方
单双引号的区别(面试题) 1.双引号可以解析变量,单引号不行 2.双引号解析转义字符,单引号不解析转义字符.但是单引号能解析 ...
- 常用颜色RGB、灰度值
128/0/0 深红 255/0/0 红 255/0/255 粉红 255/153/204 玫瑰红 153 ...
- C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 一点感想 很意外的,第一 ...
- ifconfig命令--查看、配置、启用或禁用网络接口的工具
ifconfig 是一个用来查看.配置.启用或禁用网络接口的工具,这个工具极为常用的.可以用这个工具来临时性的配置网卡的IP地址.掩码.广播地址.网关等.也可以把它写入一个文件中(比如/etc/rc. ...
- HTML <div>和<span>
块代码 <div>和<span> 1.. <style> .ccwTest { font-family: '.PingFang SC';">; co ...
- SpringMVC详解(一)------入门实例
本系列教程我们将详细的对SpringMVC进行介绍,相信你在学完本系列教程后,一定能在实际开发中运用自如. 1.什么是 SpringMVC ? 在介绍什么是 SpringMVC 之前,我们先看看 Sp ...
- 【复制】【编码】MySQL复制中的编码问题
编码背景知识 Latin-1,全称ISO 8859-1 Latin 1 对ASCII的拉丁语扩展 向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x8 ...