Redis的发布和订阅

发布和订阅

  1. 什么是发布和订阅?
  • 发布订阅是一种应用程序(系统)之间通讯,传递数据的技术手段。特别是在异构(不同语言)系统之间作用非常明显。发布订阅可以是实现应用(系统)之间的解耦合。
  • 发布订阅:类似微信中关注公众号/订阅号,公众号/订阅号发布的文章,信息。订阅者能及时获取到最新的内容。微博的订阅也是类似的。日常生活中听广播,看电视。都需要有信息的发布者,收听的人需要订阅(广播、电视需要调动某个频道)。发布订阅是一对多的关系。
  • 订阅:对某个内容感兴趣,需要实时获取新的内容。只要关注的内容有变化就能立即得
    到通知。多的一方。
  • 发布:提供某个内容,把内容信息发送给多个对此内容感兴趣的订阅者。是有主动权,是一的一方。
  • 发布订阅应用在即时通信应用中较多,比如网络聊天室,实时广播、实时提醒等。滴滴打车软件的抢单;外卖的抢单;在微信群发红包,抢红包都可以使用发布订阅实现。

Redis的发布和订阅

Redis发布订阅(pub/sub)是一种消息通信模式:发送者(publish)发送消息,订阅者(subscribe)接收消息。发布订阅也叫生产者消费者模式,是实现消息队列的一种方式。
在这里插入图片描述在这里插入图片描述

如何实现

  1. 发布订阅的相关命令:
    在这里插入图片描述
    A、publish发布消息
    语法:publish chanel message
    作用:将message消息发送到channel频道。message是要发送的消息,channel是自定
    义的频道名称(例如cctv1,cctv5),唯一标识发布者。
    返回值:数字。接收到消息订阅者的数量

    B、subscribe订阅频道
    语法:subscribe channel [channel…]
    作用:订阅一个或多个频道的信息
    返回值:订阅的消息
    C、unsubscribe退订频道

    语法:unsubscribe channel [channel]
    作用:退出指定的频道,不订阅。
    返回值:退订的告知消息

    命令行实现

    注意要启动订阅者,等待接收发布者的消息,否则订阅者接收不到消息

    A、开启4个redis客户端,3个客户端作为消息订阅者,1个为消息发布者
    在这里插入图片描述
    B、让3个消息订阅者订阅某个频道主题:subscribe channel
    在订阅者的三个窗口中分别启动redis客户端,redis安装目录/src下执行./redis-cli

    在这里插入图片描述
    C、让1个消息发布者向频道主题上发布消息:publish channel message在发布者窗口
    在这里插入图片描述
    D、 然后观察消息的发布和订阅情况,在任意一个订阅窗口
    在这里插入图片描述

编程实现

  • JedisPubSub类:Jedis中的JedisPubSub类是Jedis的一个抽象类,此类定义了publish/subscribe的回调方法,通过继承JedisPubSub类,重写回调方法。实现java中Redis的发布订阅。当Reids发生发布或订阅的相关事件时会调用这些回调方法。只在回调方法中实现自己的业务逻辑。

  • onMessage():发布者发布消息时,会执行订阅者的回调方法onMessage(),接收发布的消息。在此方法实现消息接收后的,自定义业务逻辑处理,比如访问数据库,更新库存等。

A、订阅者SUB工程,订阅者MyRedisSubScribe继承 JedisPubSub

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class MyRedisSubScribe extends JedisPubSub {
    /**
     * 当订阅者接收到消息时回自动调用改方法
     * @param channel 频道的名称
     * @param message 发布的消息
     */
    @Override
    public void onMessage(String channel, String message) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("我是订阅者:订阅频道[" + channel + "],收到的消息是:[" + message + "],时间为:[" + df.format(new Date()) + "]");
    }

    public static void main(String[] args) {
        // 创建Jedis
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        // 密码认证
        jedis.auth("123456");
        // 创建redisSubScribe对象
        MyRedisSubScribe redisSubScribe = new MyRedisSubScribe();
        // 从Redis订阅 cctv6
        jedis.subscribe(redisSubScribe, "cctv6");
    }
}

B、 发布者工程,定义MyRedisPublish发布消息

import redis.clients.jedis.Jedis;

public class MyRedisPublish {
    public static void main(String[] args) {
        // 创建Jedis
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.auth("123456");
        jedis.publish("cctv6", "战狼2");
        System.out.println("发布消息完毕....");
    }
}

C、 执行程序,先启动订阅者,在运行发布者
在这里插入图片描述

Redis发布订阅与ActiveMQ的比较

(1)ActiveMQ支持多种消息协议,包括AMQP,MQTT,Stomp等,并且支持JMS规范,但Redis没有提供对这些协议的支持;

(2)ActiveMQ提供持久化功能,但Redis无法对消息持久化存储,一旦消息被发送,如果没有订阅者接收,那么消息就会丢失;

(3)ActiveMQ提供了消息传输保障,当客户端连接超时或事务回滚等情况发生时,消息会被重新发送给客户端,Redis没有提供消息传输保障。

### 三级标题:Spring Boot 中集成 Redis 发布订阅功能 在 Spring Boot 项目中集成 Redis发布订阅功能,可以通过简洁的配置强大的集成能力,快速实现消息的发布订阅,极大地提升开发效率[^1]。 #### Redis 发布订阅功能的基本流程 Redis发布订阅功能允许客户端通过频道(Channel)进行消息通信,发布者将消息发送到指定频道,所有订阅该频道的客户端均可接收消息。在 Spring Boot 中,可以通过以下方式实现这一功能。 #### 添加依赖 在 `pom.xml` 文件中引入 Spring Boot 与 Redis 集成所需的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` #### 配置 Redis 在 `application.properties` 文件中配置 Redis 的连接信息: ```properties spring.redis.host=localhost spring.redis.port=6379 ``` #### 创建消息监听器 创建一个监听器类来接收 Redis 发布的消息: ```java import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.stereotype.Component; @Component public class RedisReceiver implements MessageListener { @Override public void onMessage(Message message, byte[] pattern) { System.out.println("Received message: " + message.toString()); } } ``` #### 配置监听适配器消息监听容器 通过配置类注册监听适配器消息监听容器,订阅特定频道: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; @Configuration public class RedisConfig { @Bean public MessageListenerAdapter messageListenerAdapter(RedisReceiver receiver) { return new MessageListenerAdapter(receiver); } @Bean public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(listenerAdapter, new ChannelTopic("news")); return container; } } ``` #### 发送消息 通过 `RedisTemplate` 向指定频道发送消息: ```java import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @Service public class RedisPublisher { private final StringRedisTemplate redisTemplate; public RedisPublisher(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } public void publish(String channel, String message) { redisTemplate.convertAndSend(channel, message); } } ``` #### Redis 发布订阅的局限性 需要注意的是,Redis发布订阅功能是即时广播机制,不支持消息持久化。若订阅者未在线,将无法收到历史消息。此外,Redis 没有提供消息传输保障,例如重试机制或事务回滚等[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值