• Spring Data Redis实现消息队列——发布/订阅模式


    一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式。利用redis这两种场景的消息队列都能够实现。

    定义:
    生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列,谁先抢到消息谁就会从队列中取走消息;即对于每个消息只能被最多一个消费者拥有。
    发布者订阅者模式:发布者生产消息放到队列里,多个监听队列的消费者都会收到同一份消息;即正常情况下每个消费者收到的消息应该都是一样的。


    下面就以Spring Data Redis实现简单的消息“发布/订阅”服务。

    spring-redis使用RedisMessageListenerContainer进行消息监听,客户程序需要自己实现MessageListener,并以指定的topic注册到RedisMessageListenerContainer,这样,在指定的topic上如果有消息,RedisMessageListenerContainer便会通知该MessageListener。

    下面是在spring配置文件中配置spring-redis:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">
    
        <!-- 引入jedis配置文件 -->
        <context:property-placeholder location="classpath*:resource/redis.properties" />
       
        <context:component-scan base-package="com.ljq.durian" />
    
        <!-- jedis pool配置 --> 
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxIdle" value="${redis.maxIdle}" />
            <property name="maxTotal" value="${redis.maxActive}" />
            <property name="maxWaitMillis" value="${redis.maxWait}" />
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />
            <property name="testOnReturn" value="${redis.testOnReturn}" />
        </bean>
        
        <!-- spring data redis -->  
        <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
            <property name="hostName" value="${redis.host}"/>  
            <property name="port" value="${redis.port}"/>  
            <property name="poolConfig" ref="jedisPoolConfig"></property>  
            <property name="timeout" value="${redis.timeout}"></property>  
            <property name="usePool" value="true"></property>  
        </bean>  
        
        <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
            <property name="connectionFactory" ref="jedisConnectionFactory"/>  
            <property name="defaultSerializer">  
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>  
            </property>  
        </bean>  
        
        <bean id="redisMessageListener" class="com.ljq.durian.common.listener.RedisMessageListener">  
            <property name="redisTemplate" ref="redisTemplate"/>  
        </bean>  
    
        <bean id="redisContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
            <property name="connectionFactory" ref="jedisConnectionFactory" />
            <property name="messageListeners">
                <map>
                    <entry key-ref="redisMessageListener">
                        <list>
                            <!-- 普通订阅,订阅具体的频道 -->
                            <bean class="org.springframework.data.redis.listener.ChannelTopic">
                                <constructor-arg value="topic.channel" />
                            </bean>
                            <!-- 模式订阅,支持模式匹配订阅,*为模糊匹配符 -->
                            <bean class="org.springframework.data.redis.listener.PatternTopic">
                                <constructor-arg value="topic.*" />
                            </bean>
                            <!-- 匹配所有频道 -->
                            <bean class="org.springframework.data.redis.listener.PatternTopic">
                                <constructor-arg value="*" />
                            </bean>
                        </list>
                    </entry>
                </map>
            </property>
        </bean>
         
    </beans>

    上面例子中,最后三个bean的配置是实现发布/订阅服务的关键,RedisMessageListener是自己写的实现了org.springframework.data.redis.connection.MessageListener的业务类,并以“topic.channel” 这个topic注册到RedisMessageListenerContainer。RedisMessageListenerContainer在消息到达后负责通知MessageListener。
    下面是RedisMessageListener的代码:

    package com.ljq.durian.common.listener;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.connection.MessageListener;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.RedisSerializer;
    
    
    public class RedisMessageListener implements MessageListener {
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
    
        @Override
        public void onMessage(Message message, byte[] pattern) {
            RedisSerializer<?> serializer = redisTemplate.getValueSerializer();
            Object channel = serializer.deserialize(message.getChannel());
            Object body = serializer.deserialize(message.getBody());  
            System.out.println("主题: " + channel);
            System.out.println("消息内容: " + String.valueOf(body));
        }
    
        public RedisTemplate<String, String> getRedisTemplate() {
            return redisTemplate;
        }
    
        public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
            this.redisTemplate = redisTemplate;
        }
    }

    这样,应用启动时,消息的订阅方(subscriber)就注册好了。这时候只要使用一个简单的程序,模拟publisher,向指定topic发布消息,RedisMessageListener就可以接收到消息,spring-redis的写法是这样:

    redisTemplate.convertAndSend("topic.channel", "hello world!");
  • 相关阅读:
    消息中间件——RabbitMQ(六)理解Exchange交换机核心概念!
    消息中间件——RabbitMQ(五)快速入门生产者与消费者,SpringBoot整合RabbitMQ!
    消息中间件——RabbitMQ(四)命令行与管控台的基本操作!
    消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!
    LayUI的基本使用
    Git报错:Your branch is up to date with 'origin/master'.
    Git报错:Please tell me who you are.
    Git报错:Permission denied (publickey)
    在 windows 上安装 git 2.22
    在 windows 上安装 git 2.15
  • 原文地址:https://www.cnblogs.com/linjiqin/p/6277537.html
Copyright © 2020-2023  润新知