Python基于redis的消息队列,订阅发布模式

有些情况,需要用redis消息发布订阅来进行某些服务数据通信,下面是封装的put和get方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project : pythonProject
# filename : redsentpu
# author : ly_13
# date : 4/7/2023
import json
import threading
import time

import redis
from threading import Thread


class RedisMsgCache(object):
    def __init__(self, channel):
        self.connection_pool = redis.ConnectionPool(host='10.66.8.111', port=6379, db=6, password='nineven')
        self.__conn = redis.Redis(connection_pool=self.connection_pool)  # 连接redis
        self.channel = channel

    def put(self, msg):
        self.__conn.publish(self.channel, json.dumps(msg))  # 根据提供的频道进行消息发布
        return True

    def subscribe(self, ):
        pub = self.__conn.pubsub()  # 打开收音机
        pub.subscribe(self.channel)  # 调频道
        pub.parse_response()  # 准备接收
        return pub

    def get(self):
        messages = self.subscribe()
        data = messages.parse_response()
        try:
            return json.loads(data[2])
        except:
            return data[2]



class MessageXx(RedisMsgCache):
    def __init__(self, channel):
        super().__init__(channel)


def put_message(x: MessageXx):
    while True:
        msg = f"{time.time()}"
        x.put(msg)
        print(f"{threading.currentThread()} 发送消息:{msg}")
        time.sleep(1)


def get_message(x: MessageXx):
    while True:
        print(f"{threading.currentThread()} 获取消息:{x.get()}")


if __name__ == '__main__':
    x = MessageXx('test-channel')
    # 启动生产者
    Thread(target=put_message, args=(x,)).start()

    # 启动接受者
    Thread(target=get_message, args=(x,)).start()
    Thread(target=get_message, args=(x,)).start()

运行打印日志如下:

<Thread(Thread-1, started 7812)> 发送消息:1680926148.241893
<Thread(Thread-2, started 3732)> 获取消息:1680926148.241893
<Thread(Thread-3, started 9764)> 获取消息:1680926148.241893
<Thread(Thread-2, started 3732)> 获取消息:1680926149.2496572
<Thread(Thread-3, started 9764)> 获取消息:1680926149.2496572
<Thread(Thread-1, started 7812)> 发送消息:1680926149.2496572

可以看到,发送消息之后,两个订阅这都会收到消息。

总结

Pub/Sub 最大的优势就是,支持多组生产者、消费者处理消息。但除了这一个优点之外,剩下的都是缺点了

因为 Pub/Sub 的实现原理非常简单,它没有基于任何数据类型,也没有做任何的数据存储,只是单纯地为生产者、消费者建立「数据转发通道」,把符合规则的数据,从一端转发到另一端。

缺点:

  1. 发布订阅模式是"发后既忘"的工作模式,如果订阅者离线,那么重连之后不能消费之前的历史消息
  2. 无法持久化保存消息,如果 Redis 服务器宕机或重启,那么所有的消息将会丢失
  3. 积压的消息不能太多,否则也会丢数据【可以通过client-output-buffer-limit这个参数配置
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis消息队列是指利用Redis实现的一种基于发布/订阅模式消息传递机制。它可以实现异步处理任务,提高系统性能并且可以扩展到分布式系统中。下面进行详细讲解。 ## 一、Redis消息队列的原理 Redis消息队列实现原理是利用Redis发布/订阅机制,通过将消息发送者称为“发布者”,将消息接收者称为“订阅者”,实现消息的传递和处理。 在Redis消息队列中,发布者将消息发布到一个频道中,订阅者从该频道中获取消息,完成相应的处理。具体流程如下: 1. 发布者将消息发布到指定频道中。 2. 订阅者向Redis服务器订阅指定频道的消息。 3. Redis服务器将频道中的消息推送给所有订阅该频道的订阅者。 4. 订阅者接收到消息后,执行相应的操作。 ## 二、Redis消息队列的应用 1. 异步任务处理 当需要执行耗时的任务时,可以使用Redis消息队列实现异步处理,将任务放入队列中,由消费者进行处理,从而避免阻塞主线程,提高系统性能。 2. 实时消息推送 当需要向多个客户端实时推送消息时,可以使用Redis消息队列实现,将消息发布到指定频道中,订阅该频道的客户端即可接收到消息。 3. 日志处理 当需要将日志记录到文件或者数据库中时,可以使用Redis消息队列实现,将日志信息放入队列中,由消费者进行处理,从而提高系统性能。 ## 三、Redis消息队列的代码实现 Python代码实现Redis消息队列: ```python import redis class RedisQueue(object): def __init__(self, queue_name, redis_host='localhost', redis_port=6379): """ 初始化Redis连接 """ self.redis_conn = redis.StrictRedis(host=redis_host, port=redis_port, db=0) self.queue_name = queue_name def put(self, data): """ 将数据放入队列 """ self.redis_conn.rpush(self.queue_name, data) def get(self, block=True, timeout=None): """ 从队列中获取数据 """ if block: data = self.redis_conn.blpop(self.queue_name, timeout=timeout) else: data = self.redis_conn.lpop(self.queue_name) if data: return data.decode('utf-8') else: return None ``` 其中,put方法将数据放入队列,get方法从队列中获取数据。 使用示例: ```python queue = RedisQueue('test_queue') queue.put('hello world') data = queue.get() print(data) ``` 以上就是Redis消息队列的详细讲解和代码实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值