消息队列(2) -- Redis实现消息队列(多应用)

异步任务: 很多时候服务器做的事情不需要客户端等待,所以可以把这些任务异步去做,主要原理是处理通知消息,然后针对通知消息通常是采取的队列结构。

实现消费者和生产者的方式很多,可以使用Python的标准库Queue:

import random
import time
from Queue import Queue
from threading import Thread

queue = Queue(10)

class Producer(Thread):
    def run(self):
        while True:
            elem = random.randrange(9)
            queue.put(elem)
            print "厨师 {} 做了 {} 饭 --- 还剩 {} 饭没卖完".format(self.name, elem, queue.qsize())
            time.sleep(random.random())

class Consumer(Thread):
    def run(self):
        while True:
            elem = queue.get()
            print "吃货{} 吃了 {} 饭 --- 还有 {} 饭可以吃".format(self.name, elem, queue.qsize())
            time.sleep(random.random())

def main():
    for i in range(3):
        p = Producer()
        p.start()
    for i in range(2):
        c = Consumer()
        c.start()

if __name__ == '__main__':
    main()


Redis队列

redis有两种方式来实现消息队列:

  1. 生产者消费模式(不推荐使用):让一个或者多个客户端监听消息队列,一旦消息达到,消费者马上消费,谁先抢到就算谁的,如果消息队列里面没有消息,那么消费者就继续监听。
  2. 发布订阅模式:一个或者多个客户端订阅消息频道,只要发布者发布消息,所有的订阅者都会收到消息,订阅者之间是平等的。

发布订阅者模式:

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

class publisher():
    def __init__(self, topic='', host='127.0.0.1', port=6379, db=0):
        self.srv = redis.StrictRedis(host=host, port=port, db=0, charset='utf-8', decode_responses=True)
        self.topic = topic # 这个topic就是发布的频道

    def publish(self, msg=''):
        self.srv.publish(self.topic, msg) # 往该频道里面发布消息

class subscriber():
    def __init__(self, topic, host='127.0.0.1', port=6379, db=0):
        self.srv = redis.StrictRedis(host=host, port=port, db=0, charset='utf-8', decode_responses=True)
        self.pubsub = self.srv.pubsub(ignore_subscribe_messages=True)
        self.pubsub.subscribe(topic)  # 订阅频道为topic

    def listen(self):
        for message in self.pubsub.listen():
            print(message)  # 这里可以获取频道里面的每一条信息
            yield message['data']

所以这里实例化publisher()传入topic其实是创建topic频道,调用它的.publish()方法可以往频道里面发布信息。
实例化subscriber()传入topic其实是订阅topic频道,调用它的.listen()方法可以获取频道里面发布的消息。

使用上面构造的Pubsub类

 def p():
     pub = publisher(topic='test')
     while 1:
         time.sleep(3)
         pub.publish(msg='Hello, Test')

pt = threading.Thread(target=p)
pt.setDaemon(True)
pt.start()

创建一个名为test的频道,每过三秒钟往频道发送一条信息

sub = subscriber(topic='test')
    listen = sub.listen()
    for msg in listen:
        print(msg)

订阅这个频道,并且打印出收到的消息

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值