Springboot集成Redis实现发布订阅功能(Java Lettuce客户端)

18 篇文章 1 订阅
3 篇文章 0 订阅

Redis 发布订阅架构

Redis的发布订阅机制包括三个部分,发布者,订阅者和Channel,这里的Channel类似于Kafka中的topic的概念。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3L20gwYJ-1625193593259)(nis/image-20210702095603264.png)]

发布者和订阅者都是Redis客户端,Channel则为Redis服务器端,可以理解为一种特殊的数据存储结构。发布者将消息发送到某个的频道,订阅了这个频道的订阅者就能接收到这条消息。

Redis的这种发布订阅机制与基于主题的发布订阅类似,Channel相当于主题。

使用Java Lettuce客户端实现Redis发布订阅

发布者

消息发布者的代码很简单,就定义一个普通的方法,指定要发布到的channel和要发布的消息即可。

package it.aspirin.learnredis.pub;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * The type Publish service.
 */
@Service
public class PublishService {
    private final static Logger log = LoggerFactory.getLogger(PublishService.class);
    @Resource
    private StringRedisTemplate stringRedisTemplate;


    /**
     * Publish.
     *
     * @param topicName the topic name
     * @param message   the message
     */
    public void publish(String topicName, String message) {
        stringRedisTemplate.convertAndSend(topicName, message);
    }
}

订阅者

消息订阅者的代码同样简单。方法传入订阅到的消息,然后进行处理即可。注意这里并没有指定订阅者订阅的通道是什么。

package it.aspirin.learnredis.listener;

import org.springframework.stereotype.Service;

/**
 * The type Test listener.
 */
@Service
public class TestListener {

    /**
     * Receive message.
     *
     * @param msg the msg
     */
    public void receiveMessage(String msg){
        System.out.println(" subscribe msg = " + msg);

    }

    /**
     * Receive message 2.
     *
     * @param msg the msg
     */
    public void receiveMessage2(String msg){
        System.out.println(" subscribe msg2 = " + msg);

    }
}

配置

在订阅者的代码中并没有指定要订阅的channel。那必定在其他地方指定了,否则订阅者就不知道要消费哪个channel的数据了。

	/**
     * Container redis message listener container.
     *
     * @param connectionFactory the connection factory
     * @param listenerAdapter1  the listener adapter 1
     * @param listenerAdapter   the listener adapter
     * @return the redis message listener container
     */
    @Bean
    public RedisMessageListenerContainer container(LettuceConnectionFactory connectionFactory,
                                                   //这里可以指定多个MessageListenerAdapter,MessageListenerAdapter名字要与下面定义的bean的方法名字一致,否则会注入不进来
                                                   MessageListenerAdapter listenerAdapter1,
                                                   MessageListenerAdapter listenerAdapter){
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //这里将channel的订阅者添加到container中,并指定要消费的channel
        container.addMessageListener(listenerAdapter1,new PatternTopic("TEST_TOPIC"));
        container.addMessageListener(listenerAdapter,new PatternTopic("TEST_TOPIC"));
        return container;
    }

    /**
     * 绑定消息监听者和接收监听的方法,必须要注入这个监听器,不然会报错
     * 这里的listenerAdapter1要与上面container中定义的名字一致
     * @param sub the sub
     * @return the message listener adapter
     */
    @Bean
    public MessageListenerAdapter listenerAdapter1(TestListener sub){
        //这个地方 是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用TestListener中的“receiveMessage”方法
        return new MessageListenerAdapter(sub,"receiveMessage");
    }

    /**
     * Listener adapter message listener adapter.
     * 这里的listenerAdapter要与上面container中定义的名字一致
     * @param sub the sub
     * @return the message listener adapter
     */
    @Bean
    public MessageListenerAdapter listenerAdapter(TestListener sub){
        //这里通过反射的放射调用TestListener中的receiveMessage2方法
        return new MessageListenerAdapter(sub,"receiveMessage2");
    }

Redis发布订阅的缺点

  • 消息无法持久化,存在丢失风险,即消息一经发布,即使没有任何订阅方处理,该条消息就会丢失
  • 没有类似ACK的机制,即发布方不会确保订阅方成功接收
  • 广播机制,下游消费能力取决于消费方本身。广播机制无法通过添加多个消费方增强消费能力,因为这和发布/订阅模型本身的目的是不符的.广播机制的目的是一个一个发布者被多个订阅进行不同的处理

以上三个缺点可以说都是非常致命的,因此在考虑使用Redis发布订阅功能的时候一定要非常慎重。

Redis发布/订阅应用场景

由于Redis发布/订阅模型存在的缺陷,所以使用前需要考虑如下几点:

  • 对于消息处理可靠性要求不强
  • 消费能力无需通过增加消费方进行增强
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值