redis pub/sub

Redis 的发布订阅(Pub/Sub)是一种基于消息的通信模式,用于实现不同组件、服务或客户端之间的异步通信。它遵循 "发布者 - 订阅者" 模型,核心思想是解耦消息的发送者(发布者)和接收者(订阅者),使它们无需直接交互即可传递信息。

核心概念

  1. 频道(Channel)消息的传输媒介,类似广播电台的频率。发布者向指定频道发送消息,订阅者通过订阅频道接收消息。频道是动态创建的,无需提前定义,首次被引用时自动创建。

  2. 发布者(Publisher)发送消息的一方,无需关心谁在接收消息,只需将消息发送到指定频道。

  3. 订阅者(Subscriber)接收消息的一方,需提前订阅感兴趣的频道。订阅后,会收到该频道所有新发布的消息(历史消息不会被回溯)。

基本工作流程

  1. 订阅者通过 SUBSCRIBE 命令订阅一个或多个频道。
  2. 发布者通过 PUBLISH 命令向指定频道发送消息。
  3. Redis 服务器将消息实时推送给所有订阅了该频道的订阅者。
  4. 订阅者可通过 UNSUBSCRIBE 命令取消订阅。

关键特性

  • 实时性:消息一经发布,立即推送给订阅者(无持久化,错过即丢失)。
  • 多对多通信:一个频道可被多个订阅者订阅,一个发布者可向多个频道发送消息。
  • 模式匹配:支持通过 PSUBSCRIBE 命令订阅符合特定模式的频道(如 news_* 匹配所有以 news_ 开头的频道)。
  • 轻量级:协议简单,性能高效,适合高频次、低延迟的消息传递。

适用场景

  1. 实时通知:如系统通知、状态更新、聊天消息等。
  2. 事件广播:分布式系统中,一个服务的事件需要被多个服务感知(如订单状态变更通知库存、支付等服务)。
  3. 日志收集:多个应用实例将日志发送到指定频道,由一个集中服务订阅并处理。
  4. 简单的消息队列:虽然功能有限,但可快速实现简单的生产者 - 消费者模型。

局限性

  1. 无消息持久化:若订阅者离线,期间的消息会丢失(需持久化可考虑 Redis Stream 或专业消息队列)。
  2. 无消息确认机制:Redis 不保证消息一定被订阅者接收。
  3. 阻塞式接收:订阅者接收消息是阻塞的,需单独线程 / 进程处理。

py程序示例

import redis
import threading
import time

# 连接 Redis 服务器
# 注意:请根据实际情况修改 Redis 连接参数
r = redis.Redis(
    host='localhost',
    port=6379,
    db=0,
    decode_responses=True  # 自动解码为字符串,避免bytes类型
)

def publisher(channel):
    """发布者函数:向指定频道发送消息"""
    try:
        count = 1
        while True:
            message = f"这是第 {count} 条消息"
            # 发布消息到指定频道
            r.publish(channel, message)
            print(f"已发布: {message} 到频道 {channel}")
            
            count += 1
            time.sleep(2)  # 每2秒发送一条消息
    except KeyboardInterrupt:
        print("\n发布者已停止")

def subscriber(channel):
    """订阅者函数:从指定频道接收消息"""
    try:
        # 创建订阅对象
        pubsub = r.pubsub()
        # 订阅指定频道
        pubsub.subscribe(channel)
        
        print(f"已订阅频道 {channel},等待消息...")
        
        # 循环监听消息
        for message in pubsub.listen():
            # 过滤掉订阅确认消息
            if message['type'] == 'message':
                print(f"\n收到消息: {message['data']} 来自频道 {message['channel']}")
    except KeyboardInterrupt:
        print("\n订阅者已停止")

if __name__ == "__main__":
    # 定义要使用的频道名称
    channel_name = "demo_channel"
    
    # 创建并启动订阅者线程
    sub_thread = threading.Thread(target=subscriber, args=(channel_name,), daemon=True)
    sub_thread.start()
    
    # 等待订阅者准备就绪
    time.sleep(1)
    
    # 启动发布者
    try:
        publisher(channel_name)
    except KeyboardInterrupt:
        print("\n程序已退出")

总结

Redis Pub/Sub 是一种轻量级、实时的消息通信模式,适合对消息可靠性要求不高、追求简单高效的场景。若需要消息持久化、重试机制等高级功能,可考虑 Redis Stream 或 Kafka、RabbitMQ 等专业消息队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值