spring boot RedisMQ——生产者消费者模式

Posted 依米欧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot RedisMQ——生产者消费者模式相关的知识,希望对你有一定的参考价值。

1.配置redis

在application.properties文件中加入redis的配置信息

#redis
gmall.redis.host=172.16.19.259
gmall.redis.port=6379
gmall.redis.pass=Gworld2017
gmall.redis.database=7
gmall.redis.timeout=5000

配置spring-redis.xml文件

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
    xmlns:redis="http://www.springframework.org/schema/redis"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
            http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
            http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis-1.0.xsd"
    default-lazy-init="false">
    <bean id="redisConnectionFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
        primary="true">
        <property name="hostName" value="${gmall.redis.host}" />
        <property name="port" value="${gmall.redis.port}" />
        <property name="password" value="${gmall.redis.pass}" />
        <property name="timeout" value="${gmall.redis.timeout}" />
        <property name="database" value="${gmall.redis.database}" />
    </bean>
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
        primary="true">
        <property name="connectionFactory" ref="redisConnectionFactory" />
        <property name="exposeConnection" value="true" />
        <property name="keySerializer">
            <bean
                class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="valueSerializer">
            <bean
                class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
        <property name="hashKeySerializer">
            <bean
                class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="hashValueSerializer">
            <bean
                class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
    </bean>
</beans>

2、编写RedisUtil类

public class RedisUtil {
    private static Logger logger = LoggerFactory.getLogger(RedisUtil.class);

    @SuppressWarnings("rawtypes")
    private static RedisTemplate getRedisTemplate() {
        return (RedisTemplate) SpringBeanFactoryUtils.getBean("redisTemplate");
    }

    @SuppressWarnings("unchecked")
    public static Long addRedisSet(String redisKey, Object value) {
        Long result = getRedisTemplate().opsForSet().add(redisKey, value);
        if (logger.isDebugEnabled()) {
            logger.debug("result=" + result);
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    public static void leftPush(String key, String value) {
        getRedisTemplate().opsForList().leftPush(key, value);
        //getRedisTemplate().opsForList().leftPop(key);
    }
    @SuppressWarnings("unchecked")
    public static String rightPop(String key,long timeout,TimeUnit unit) {
        Object obj =  getRedisTemplate().opsForList().rightPop(key, timeout, unit);
        String str =  (String) obj;
        return str;
    }
    @SuppressWarnings("unchecked")
    public static Object rightPopAndLeftPush(String sourceKey, String destinationKey) {
        Object value = getRedisTemplate().opsForList().rightPopAndLeftPush(sourceKey, destinationKey);
        return value;
    }
}
SpringBeanFactoryUtils类

package com.gcard.queue.utils;

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class SpringBeanFactoryUtils   implements ApplicationContextAware {    
    private static ApplicationContext appCtx;    
    /**  
     * 此方法可以把ApplicationContext对象inject到当前类中作为一个静态成员变量。  
     * @param applicationContext ApplicationContext 对象.  
     * @throws BeansException  
     * @author wangdf 
     */    
     
    public void setApplicationContext( ApplicationContext applicationContext ) throws BeansException {    
        appCtx = applicationContext;    
    }  
       
    /** 
     * 获取ApplicationContext 
     * @return 
     * @author wangdf 
     */  
    public static ApplicationContext getApplicationContext(){  
        return appCtx;  
    }  
       
    /**  
     * 这是一个便利的方法,帮助我们快速得到一个BEAN  
     * @param beanName bean的名字  
     * @return 返回一个bean对象  
     * @author wangdf 
     */    
    public static Object getBean( String beanName ) {
        return appCtx.getBean( beanName );
    }    
    @SuppressWarnings("unchecked")
    public static Object getBean( Class requiredType ) {
        return appCtx.getBean(requiredType);
    }    
}

 

3、模拟生产者

public class TaskProducer implements Runnable {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    public void run() {
        try {
            for(int i=0;i<5;i++){
                RedisUtil.leftPush("task-queue", "value_" + i);
                logger.info("插入一个新的任务:" + "value_" + i);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

}

4、模拟消费者

public class TaskConsumer implements Runnable {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    public void run() {
        while (true) {
            try {
                String taskid = (String) RedisUtil.rightPopAndLeftPush("task-queue", "tmp-queue");//取出消息放到临时队列
                // Thread.sleep(1000);
                // RedisUtil.rightPop("tmp-queue");//非阻塞

                // 阻塞式brpop,List中无数据时阻塞,参数0表示一直阻塞下去,直到List出现数据
                String str = RedisUtil.rightPop("tmp-queue", 0, TimeUnit.MINUTES);//阻塞,取出临时队列
                logger.info("线程取数据:{}", str);
                logger.info(str + "处理成功,被清除");

            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
        /*
         * if(random.nextInt(13) % 7 == 0){
         * RedisUtil.rightPopAndLeftPush("tmp-queue","task-queue");//弹回任务队列
         * logger.info(taskid+"处理失败,被弹回任务队列"); }else{
         * RedisUtil.rightPop("tmp-queue"); logger.info(taskid+"处理成功,被清除"); }
         */
    }

}

5、独立消费者作为一个项目(监听器)

在application-context.xml文件配置bean,启动项目后就会执行这个监听器

<bean class="com.gcard.longcode.manager.impl.MessageQueueServiceImpl" init-method="messageListener"/>

 



以上是关于spring boot RedisMQ——生产者消费者模式的主要内容,如果未能解决你的问题,请参考以下文章

详解Spring Boot中的RabbitMQ

RabbitMq+Spring boot 消息生产者向队列发送消息

Spring Boot MQTT Too many publishes in progress错误的解决方案

Spring Boot (十三): Spring Boot 整合 RabbitMQ

spring-boot-route(十三)整合RabbitMQ

java——spring boot集成RabbitMQ——路由模式——实现生产者