利用Redis发布订阅模式、SSE实现分布式实时站内信系统

文章浏览阅读3.9k次,点赞5次,收藏25次。站内信功能在各大系统中被广泛应用,本文结合工作的实际场景,使用javaspringboot框架、Redis,探讨一种轻量化的实现分布式实时站内信系统方案。_sse分布式


前言

站内信功能在各大系统中被广泛应用,本文结合工作的实际场景,使用java springboot框架、Redis,探讨一种轻量化的实现分布式实时站内信系统方案。


一、SSE是什么?

 SSE (Server-sent Events )是 WebSocket 的一种轻量代替方案,可实现服务端主动向客户端推送消息,例如在扫码支付结果反馈、邮箱服务的新邮件提醒,微博的新消息推送,SSE 都是不错的选择

在Springboot框架中已经集成,无需像websocket方式一样需要单独引入依赖,相对轻量。
浏览器断线自动重连,减少了前端业务逻辑。

二、单机与集群的站内信实现方式有何区别?

单机场景下逻辑较为简单,消息的发送端和用户登录在同一个节点,程序只需要在内存中找到所需的SseEmitter对象并发送即可。但生产环境往往不会只部署一个节点,那此时用户订阅的SseEmitter对象和消息的发送端很可能不在同一个节点,假设用户订阅产生的SseEmitter对象在A节点,但是消息发送在B节点,如何让A节点感知到有实时消息并调用SseEmitter.send()发送数据,需要一套中心化的消息推送机制才能实现。

三、Redis 发布、订阅模式有何特点?

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

下图展示了客户端与频道之间的订阅关系

在这里插入图片描述

下图展示了消息推送数据流向

在这里插入图片描述

相对于市面上其他的主流的消息中间件产品,如Kafka、RabbitMQ、ActiveMQ, RocketMQ,Redis的订阅发布功能相对轻量,但由于其数据只在内存中分发,不持久化的特点,当客户端程序重启时可能会发生丢失在重启期间的数据的问题,所以Redis的发布订阅功能,只针对业务体量小、追求轻量化、对数据完整性要求不高的场景下比较适合使用。

四、代码演示

1.数据模型

消息发布的范围分为全体广播、工作室广播、个人私信
全体广播:所有用户都能收到消息
工作室广播:仅指定工作室内的成员能够接收到消息
个人私信:仅个人能收到消息

用户表:

在这里插入图片描述

用户与工作室关系表:

在这里插入图片描述
具体数据可以下载源码启动后访问:http://127.0.0.1:9090/h2

小结

用户zhangsan、lisi同属团队1,wangwu属于团队2

2.引入依赖

Redission:

 <dependency>
     <groupId>org.redisson</groupId>
     <artifactId>redisson</artifactId>
     <version>3.17.3</version>
</dependency>

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3.配置RedissonClient

	@Bean
    public RedissonClient redissonClient() { 
   
        Config config = new Config();
        // 单节点
        SingleServerConfig singleServerConfig = config.useSingleServer();
        singleServerConfig.setAddress("redis://127.0.0.1:6379");
        // 使用json序列化方式
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        config.setCodec(new JsonJacksonCodec(objectMapper));
        return Redisson

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/87802.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注