Redis实现简单消息队列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis实现简单消息队列相关的知识,希望对你有一定的参考价值。

参考技术A 打开浏览器,输入地址,按下回车,打开了页面。于是一个 HTTP 请求( request )就由客户端发送到服务器,服务器处理请求,返回响应( response )内容。

我们每天都在浏览网页,发送大大小小的请求给服务器。有时候,服务器接到了请求,会发现他也需要给另外的服务器发送请求,或者服务器也需要做另外一些事情,于是最初们发送的请求就被阻塞了,也就是要等待服务器完成其他的事情。

更多的时候,服务器做的额外事情,并不需要客户端等待,这时候就可以把这些额外的事情异步去做。从事异步任务的工具有很多。主要原理还是处理通知消息,针对通知消息通常采取是队列结构。生产和消费消息进行通信和业务实现。

上述异步任务的实现,可以抽象为生产者消费模型。如同一个餐馆,厨师在做饭,吃货在吃饭。如果厨师做了很多,暂时卖不完,厨师就会休息;如果客户很多,厨师马不停蹄的忙碌,客户则需要慢慢等待。实现生产者和消费者的方式用很多,下面使用 Python 标准库 Queue 写个小例子:

大概输出如下:

Python内置了一个好用的队列结构。我们也可以是用redis实现类似的操作。并做一个简单的异步任务。

Redis提供了两种方式来作消息队列。一个是使用 生产者消费模式 模式,另外一个方法就是 发布订阅者模式 。前者会让一个或者多个客户端监听消息队列,一旦消息到达,消费者马上消费,谁先抢到算谁的,如果队列里没有消息,则消费者继续监听。后者也是一个或多个客户端订阅消息频道,只要发布者发布消息,所有订阅者都能收到消息,订阅者都是平等的。

主要使用了redis提供的blpop获取队列数据,如果队列没有数据则阻塞等待,也就是监听。

使用redis的pubsub功能,订阅者订阅频道,发布者发布消息到频道了,频道就是一个消息队列。

我们分别实现了两种异步任务的后端服务,直接启动他们,就能监听redis队列或频道的消息了。简单的测试如下:

启动脚本,使用

可以分别在监听的脚本输入中看到异步消息。在异步的任务中,可以执行一些耗时间的操作,当然目前这些做法并不知道异步的执行结果,如果需要知道异步的执行结果,可以考虑设计协程任务或者使用一些工具如 RQ 或者 celery 等。

Redis实现简单的消息队列

 

 

1、问:什么是消息队列?

   答:是一个消息的链表,是一个异步处理的数据处理引擎。

2、问:有什么好处?

     答:不仅能够提高系统的负荷,还能够改善因网络阻塞导致的数据缺失。

3、问:用途有哪些?

     答:邮件发送、手机短信发送,数据表单提交、图片生成、视频转换、日志储存等。

4、问:有哪些软件?

     答:ZeroMQ、Posix、SquirrelMQ、Redis、QDBM、Tokyo Tyrant、HTTPSQS等(linux平台下)。

5、问:怎么实现?

     答:顾名思义,先入队,后出队;先把数据丢到消息队列(入队),后根据相应的key来获取数据(出队)。

6、问:Redis可以做消息队列?

     答:首先,redis设计用来做缓存的,但是由于它自身的某种特性使得它可以用来做消息队列,它有几个阻塞式的API可以使用,正是这些阻塞式的API让其有能力做消息队列;另外,做消息队列的其他特性例如FIFO(先入先出)也很容易实现,只需要一个list对象从头取数据,从尾部塞数据即可;redis能做消息队列还得益于其list对象blpop brpop接口以及Pub/Sub(发布/订阅)的某些接口,它们都是阻塞版的,所以可以用来做消息队列。

7、问:怎么做(基于ThinkPHP)?

     答:7.1 安装redis,过程(略);

       7.2 安装php-redis扩展,过程(略);

          7.3 贴代码

                          图1 入队

          

                                             图2 入队结果

          

                                              图3 出队

          

                                              图4 出队结果

          

                                               图5 完整代码

           

8、小结:redis的lPush命令将一个或多个值插入到列表头部与rPush与rPush相反;rPop命令用于溢出并返回列表的最后一个元素与lPop相反。

以上是关于Redis实现简单消息队列的主要内容,如果未能解决你的问题,请参考以下文章

使用redis实现消息队列

Redis实现简单的消息队列

浅谈三种使用Redis实现MQ的方式

手把手教你用redis实现一个简单的mq消息队列(java)

redis实现消息队列

Redis 实现消息队列 MQ