找回密码
立即注册
搜索
发回帖 发新帖

6776

积分

0

好友

853

主题
发表于 2026-3-4 10:51:22 | 查看: 309| 回复: 0

我们将以“在线购物网站”作为例子贯穿全文,帮助大家理解Redis Pub/Sub在不同场景下的应用。

1. 什么是 Redis 的 Pub/Sub 机制

专业性描述

Redis Pub/Sub(发布/订阅)是一种消息通信模式,发送者(发布者)将消息发送到指定的频道,订阅了该频道的接收者(订阅者)都会收到此消息。这种模式实现了发布者和订阅者之间的解耦,发布者不需要知道订阅者的存在,订阅者也不需要知道发布者的存在。

大白话类比

这就像电台广播。电台(发布者)在某个频率(频道)上广播节目,所有调到这个频率的收音机(订阅者)都能收到节目。电台不知道有多少收音机在收听,收音机也不知道电台在哪里,它们只通过频率这个中介联系起来。

“在线购物网站”示例

假设我们有一个在线购物网站,当有新订单生成时,需要同时做以下几件事:

  1. 发送短信通知用户
  2. 更新商品库存
  3. 记录订单日志
  4. 更新用户积分

使用Redis Pub/Sub,我们可以让订单服务发布一个消息到 order.created 频道,其他服务订阅这个频道,各自处理自己的业务逻辑。

2. 应用场景:消息发布/订阅,模式订阅

2.1 基本发布/订阅

“在线购物网站”示例

订单服务发布订单创建消息:

# 订单服务发布消息
PUBLISH order.created “订单ID: 1001, 用户ID: 2001, 金额: 299.00”

短信服务订阅该频道:

# 短信服务订阅频道
SUBSCRIBE order.created
# 收到消息后,发送短信给用户

库存服务订阅该频道:

# 库存服务订阅频道
SUBSCRIBE order.created
# 收到消息后,减少库存

2.2 模式订阅

专业性描述

模式订阅允许订阅者通过通配符一次订阅多个频道。Redis支持两种通配符:* 匹配任意多个字符,? 匹配一个字符。

“在线购物网站”示例

假设我们有多个订单相关的事件:

  • order.created 订单创建
  • order.paid 订单支付
  • order.shipped 订单发货
  • order.completed 订单完成

日志服务希望订阅所有订单相关的事件:

# 使用模式订阅
PSUBSCRIBE order.*
# 这样会收到所有以“order.”开头的事件

3. Pub/Sub 的优点、缺点、适用场景

3.1 优点

  1. 解耦:发布者和订阅者不需要知道对方的存在,只需要关注频道。
  2. 实时性:消息发布后立即推送给所有订阅者。
  3. 扩展性:可以方便地增加新的订阅者,不影响现有系统。
  4. 简单易用:Redis命令简单,无需额外组件。

“在线购物网站”示例

当我们需要增加一个新的功能:订单成功后给用户发放优惠券。只需要新增一个优惠券服务,订阅 order.completed 频道即可,不需要修改订单服务。这种基于事件的通信方式非常适合构建松耦合的分布式系统。

3.2 缺点

  1. 消息不可持久化:Redis Pub/Sub的消息是即时的,如果没有订阅者,消息就丢失了。订阅者掉线期间的消息也会丢失。
  2. 无消息堆积能力:如果订阅者处理速度慢,消息不会被缓存,会导致消息丢失。
  3. 无消息确认机制:发布者不知道消息是否被成功接收和处理。
  4. 不支持消息重试:如果处理失败,无法重新获取消息。

“在线购物网站”示例

假设短信服务在订单创建时宕机了,那么订单创建的消息就会丢失,用户收不到短信通知。而且即使短信服务恢复,也不会收到之前的消息。这对于关键业务来说是致命缺陷。

3.3 适用场景

  1. 实时通知:如在线聊天、实时弹幕。
  2. 事件广播:如配置更新、服务发现。
  3. 轻量级消息队列:对消息可靠性要求不高,允许少量丢失的场景。
  4. 解耦系统组件:组件间需要解耦,但不要求强可靠性的场景。

“在线购物网站”示例

适合使用Redis Pub/Sub的场景:

  • 用户登录/登出状态广播(用于在线用户列表)
  • 商品价格变化通知(前台展示实时更新)
  • 管理员操作广播(多个后台需要同步状态)

不适合使用Redis Pub/Sub的场景:

  • 订单支付结果通知(不能丢失)
  • 库存扣减消息(必须保证处理)
  • 积分变更记录(需要可靠传递)

4. List、Redis Pub/Sub、Redis Stream、专业级消息中间件的对比

下面我们通过“在线购物网站”的不同场景,对比这四种消息传递方式。

4.1 Redis List(列表)

专业性描述

Redis List是一个简单的列表数据结构,可以用作消息队列。生产者通过LPUSH添加消息,消费者通过RPOP或BRPOP获取消息。

“在线购物网站”示例

商品搜索服务将用户搜索关键词放入队列,异步分析搜索热点:

# 搜索服务生产消息
LPUSH search:keywords “iphone 15”
LPUSH search:keywords “华为mate60”
# 分析服务消费消息
BRPOP search:keywords 0

特点:

  • 消息可持久化
  • 支持多个消费者,但每条消息只能被一个消费者获取
  • 简单,但功能有限
  • 无消息确认机制

4.2 Redis Pub/Sub(发布/订阅)

“在线购物网站”示例

用户下单后,需要同时通知多个服务:

# 订单服务发布
PUBLISH order.paid “订单ID: 1001, 金额: 299.00”
# 多个服务订阅
# 短信服务、库存服务、积分服务等

特点:

  • 一对多广播
  • 实时推送
  • 消息不持久化
  • 无消息堆积能力

4.3 Redis Stream(流)

专业性描述

Redis 5.0引入的数据类型,专门为消息队列设计。支持消息持久化、消费者组、消息确认等特性。

“在线购物网站”示例

订单支付成功后的可靠消息传递:

# 支付服务生产消息
XADD order:payments * orderId 1001 userId 2001 amount 299.00
# 创建消费者组
XGROUP CREATE order:payments sms-group $ MKSTREAM
XGROUP CREATE order:payments stock-group $ MKSTREAM
# 不同消费者组独立消费
# 短信服务消费者组
XREADGROUP GROUP sms-group consumer1 COUNT 1 STREAMS order:payments >
# 库存服务消费者组
XREADGROUP GROUP stock-group consumer1 COUNT 1 STREAMS order:payments >

特点:

  • 消息可持久化
  • 支持消费者组,同一消息可被不同组消费
  • 支持消息确认和重试
  • 功能丰富,接近专业消息队列

4.4 专业级消息中间件(如RabbitMQ、Kafka)

“在线购物网站”示例

大规模订单处理,需要高可靠性和高吞吐量:

  • Kafka:用于用户行为日志收集,海量日志数据
  • RabbitMQ:用于订单状态同步,需要复杂路由

特点:

  • 功能最完整
  • 支持各种消息模式
  • 高可靠性、高可用性
  • 管理和运维复杂
  • 资源消耗较大

4.5 对比表格

特性 Redis List Redis Pub/Sub Redis Stream 专业消息中间件
消息持久化 支持 不支持 支持 支持
消息广播 不支持 支持 支持消费者组 支持
消息确认 不支持 不支持 支持 支持
消息重试 不支持 不支持 支持 支持
消息顺序 先进先出 无保证 有序 有序
吞吐量 中 高 中高 高
可靠性 低 低 中 高
复杂度 简单 简单 中等 复杂
适用场景 简单任务队列 实时通知广播 可靠消息队列 企业级应用

“在线购物网站”选择建议:

  1. 实时在线人数统计:使用 Pub/Sub(实时性要求高,允许丢失)
  2. 订单支付结果通知:使用 Stream(需要可靠性,但不想引入复杂中间件)
  3. 用户行为日志收集:使用 Kafka(海量数据,高吞吐)
  4. 异步发送邮件:使用 List(简单,允许少量丢失)

5. 记忆技巧与实战要点

核心口诀:
Pub/Sub是广播,实时推送不可少。
消息丢了不负责,适合通知和报警。
List能做简单队,一消费者消费掉。
Stream才是真队列,持久确认功能强。
专业中间件虽好,复杂场景再上场。

6. Redis Pub/Sub 应用架构图

Redis Pub/Sub在微服务中的架构示意图

图例解读

  1. 订单服务发布订单创建消息到 order.created 频道
  2. 短信、库存、积分、日志服务都订阅了这个频道,都会收到消息
  3. 用户服务发布用户注册消息到 user.registered 频道
  4. 日志和推送服务订阅了这个频道
  5. 商品服务发布价格更新消息到 price.updated 频道
  6. 日志和推送服务订阅了这个频道

通过这样的架构,各个服务之间完全解耦,新增服务只需要订阅感兴趣的频道,无需修改发布者代码。

7. 实战要点

选择依据:

需要广播且允许丢失:用Pub/Sub
简单队列,单消费者:用List
需要可靠性,多消费者:用Stream
企业级复杂需求:用专业消息中间件

注意事项:

  • Pub/Sub订阅后,客户端会阻塞等待消息,需要单独连接
  • Stream的消息不自动删除,需要定期清理
  • List作为队列时,注意处理消费者崩溃的情况
  • 专业消息中间件部署和维护成本较高

监控指标:

  • Pub/Sub客户端数量
  • Stream消息堆积数
  • List队列长度
  • 消息处理延迟

容灾设计:

  • Pub/Sub:订阅者断线重连后无法收到之前消息,需有补偿机制
  • Stream:配置合理的持久化策略
  • 重要业务:需要有死信队列和重试机制

性能优化:

  • 批量处理消息
  • 合理设置消费者数量
  • 监控内存使用,避免消息堆积

总结

Redis Pub/Sub是一种简单高效的发布/订阅机制,非常适合实时通知、事件广播等场景。但在需要消息可靠性、持久化的场景下,应该选择Redis Stream或专业消息中间件。在实际应用中,需要根据业务需求、可靠性要求、系统复杂度等因素综合考虑,选择合适的消息传递方式。对于希望深入探讨更多后端架构与中间件选型的朋友,欢迎访问云栈社区进行交流。




上一篇:XiebroC2渗透测试框架实战:Go/.NET跨平台C2工具的功能解析与使用教程
下一篇:TiDB 数据库 SCHEMA 设计:关于表属性与函数的常见误区与正确答案
您需要登录后才可以回帖 登录 | 立即注册

关闭

站长推荐上一条 /1 下一条

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-11-13 14:02 , Processed in 0.082784 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表