Redis怎样结合Redisson实现主题分布式订阅

梦芳大大_4361

梦芳大大_4361

2026-03-27

1007人浏览

原创

Redisson 的 RTopic 通过 Redis 原生 pub/sub 实现跨节点消息广播,依赖同一数据库、统一 Codec 和客户端本地线程池消费;不支持集群默认模式,无持久化、无 ACK、不保证顺序,适用于可丢失的轻量通知场景。

redis怎样结合redisson实现主题分布式订阅

Redisson 的 RTopic 是怎么做到跨节点接收同一主题消息的

靠 Redis 的发布订阅原语 + Redisson 封装的客户端监听机制。Redis 本身不保存订阅关系,所有 RTopic 实例都通过底层 PUBLISH/SUBSCRIBE 与 Redis 通信,但 Redisson 在客户端做了两件事:一是把 Java 方法调用转成标准 Redis 协议命令;二是为每个 RTopic 维护一个本地线程池来持续消费 SUBSCRIBE 流。多个 JVM 进程里各自 new 出来的 RTopic,只要连的是同一个 Redis,就能同时收到 PUBLISH 过来的消息。

注意:这不是 Redisson 自己搞了一套消息总线,它完全依赖 Redis 的 pub/sub 模型,所以没有消息持久化、无 ACK、不保证顺序、断连期间消息直接丢——这些不是 bug,是 Redis 原生限制。

  • 必须用同一个 Redis 数据库(database 配置一致),否则 SUBSCRIBE 到不同 db 就收不到
  • 不要在单个 RTopic 实例上调用多次 addListener(),每次都会注册新监听器,导致重复执行
  • 如果用的是 Redis 集群模式,RTopic 默认不可用(集群不支持 SUBSCRIBE),得切到单节点或开启 Redisson 的集群 pub/sub 代理模式(需配置 useSingleServer 或启用 redisson.yaml 中的 subscriptionsPerConnection)

为什么 RTopic.publish() 后有些客户端收不到消息

最常见原因是连接隔离或序列化不一致。Redis pub/sub 只传原始字节,Redisson 默认用 JsonJacksonCodec 序列化,但如果不同服务用了不同 Codec(比如一个用 StringCodec,一个用 LongCodec),发出去的是字符串 "123",收端按 long 解就会报 ClassCastException 或静默失败。

  • 所有用到同一主题的服务,必须使用完全相同的 Codec 实例(推荐全局复用一个 JsonJacksonCodec)
  • 检查 Redisson 客户端是否已初始化完成再调 getTopic(),未连接成功时 publish() 会抛 RedisTimeoutException,但默认不打印堆栈
  • 别在 Spring @PostConstruct 里直接 publish——此时 Redisson 可能还没完成订阅通道建立,建议加个简单健康检查(如 redisson.getNodesGroup().pingAll())

如何让订阅逻辑不阻塞主线程又避免内存泄漏

RTopic.addListener() 返回的是监听器 ID(long 类型),这个 ID 必须手动管理。Redisson 不会自动清理已注销的监听器,也不回收关联的线程资源。如果你在 Web 请求中反复 addListener 而不 remove,会累积大量空闲线程和闭包对象。

  • 监听器函数体里别直接引用大对象(如整个 Service Bean),容易引发 GC 压力;用弱引用或只传必要字段
  • 务必在合适的生命周期点调 topic.removeListener(listenerId),比如 Spring Bean 销毁时、Netty Channel 关闭后
  • 如果只是临时监听(例如等某个异步任务完成),建议用带超时的 CountDownLatch + Future 包裹,而不是长期 hold 住 listener

用 RTopic 替代消息队列有哪些实际代价

它轻量、低延迟,但放弃的是可靠性。你不能指望它替代 RabbitMQ 或 Kafka 来做订单通知或支付结果回调这类场景。

  • Redis 重启 = 所有未消费消息清零,没有任何重放能力
  • 网络抖动导致客户端 SUBSCRIBE 断开,重连后无法获取断连期间的消息(Redis 不存历史)
  • 单条消息最大 512MB,但实际超过几 MB 就会影响 Redis 主线程性能,且序列化/反序列化成本陡增
  • 当订阅者数量多(比如几百个实例),Redis 的 CPU 会明显上涨,因为每条 PUBLISH 都要复制给每个活跃的 SUBSCRIBE 连接

真正适合的场景其实很窄:配置变更广播、缓存失效通知、轻量级状态同步——共性是消息可丢失、内容小、消费者能自我恢复。一旦业务开始要求“至少一次”或“顺序”,就得换方案了。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

2025.08.06

2831

22

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

2026.01.26

517

25

rabbitmq和kafka有什么区别
rabbitmq和kafka有什么区别

rabbitmq和kafka的区别:1、语言与平台;2、消息传递模型;3、可靠性;4、性能与吞吐量;5、集群与负载均衡;6、消费模型;7、用途与场景;8、社区与生态系统;9、监控与管理;10、其他特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

664

5

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

2026.01.28

1108

20

RabbitMQ使用教程合集
RabbitMQ使用教程合集

RabbitMQ使用教程合集整理 RabbitMQ 基础教程、消息队列开发案例、生产者消费者、交换机与队列实战内容。

2026.05.20

204

15

RabbitMQ集群部署指南
RabbitMQ集群部署指南

RabbitMQ集群部署指南聚合 RabbitMQ 集群部署、高可用架构、镜像队列、故障恢复、监控与运维优化内容。

2026.05.20

137

12

RabbitMQ Docker实战指南
RabbitMQ Docker实战指南

RabbitMQ Docker实战指南提供 RabbitMQ Docker 镜像部署、Docker Compose、Kubernetes Operator 与云原生实践教程。

2026.05.20

162

10

什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2133

5

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.07

3474

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习