springboot2+redis 订阅发布,解决接收消息累计线程到内存溢出,使用自定义线程池接收消息

pom 添加redis

java 复制代码
		<!-- redis 缓存操作 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

发布消息

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * @author zpy
 * @date 2023/8/9 13:48
 */
@Slf4j
@Component
public class RedisMessageUtils {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 向通道发布消息
      * topic 通道名称
     */
    public void sendMessage(String topic, Object message) {
        if (!StringUtils.hasText(topic)) {
            return;
        }
        try {
            stringRedisTemplate.convertAndSend(topic, message);
            log.info("发送消息成功,topic:{},message:{}", topic, message);
        } catch (Exception e) {
            log.info("发送消息失败,topic:{},message:{}", topic, message);
            e.printStackTrace();
        }
    }

}

接收消息

java 复制代码
    /**
     * Redis消息监听器容器
     * 这个容器加载了RedisConnectionFactory和消息监听器
     * 可添加多个不同话题的redis监听器,需要将消息监听器和消息频道绑定,
     * 通过反射调用消息订阅处理器的相关方法进行业务处理
     *
     * @param  redisConnectionFactory   	连接工厂
     * @param  listener                 	Redis消息监听器
     * @param  MessageListenerAdapter   	Redis消息监听适配器
     * @return RedisMessageListenerContainer    消息监听容器
     */
    @Bean
    @SuppressWarnings("all")
    public RedisMessageListenerContainer container(RedisMessageListener listener) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactorySlave());
        // 所有的订阅消息,都需要在这里进行注册绑定
        // new PatternTopic(TOPIC_NAME1) 表示发布信息的频道
        // 可以添加多个频道以及配置不同的频道
        container.addMessageListener(listener, new PatternTopic("消息频道名称"));
        //container.addMessageListener(adapter, new PatternTopic(SystemConstants.TOPIC_NAME2));
        container.setTaskExecutor(springSessionRedisTaskExecutor());

        /**
         * 设置序列化对象
         * 特别注意:1. 发布的时候和订阅方都需要设置序列化
         *         2. 设置序列化对象必须放在 {加入消息监听器} 这步后面,不然接收器接收不到消息
         */
		/*Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(Object.class);
		ObjectMapper objectMapper = new ObjectMapper();
		objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		seria.setObjectMapper(objectMapper);
		container.setTopicSerializer(seria);*/
        return container;
    }

/** 自定义接收消息的线程池
*/
    @Bean
    public ThreadPoolTaskExecutor springSessionRedisTaskExecutor() {
        ThreadPoolTaskExecutor springSessionRedisTaskExecutor = new ThreadPoolTaskExecutor();
        springSessionRedisTaskExecutor.setCorePoolSize(8);
        springSessionRedisTaskExecutor.setMaxPoolSize(15);
        springSessionRedisTaskExecutor.setKeepAliveSeconds(10);
        springSessionRedisTaskExecutor.setQueueCapacity(1000);
        springSessionRedisTaskExecutor.setThreadNamePrefix("redis-");
        return springSessionRedisTaskExecutor;
    }

测试

java 复制代码
@Scheduled(cron = "0/10 * * * * *")
	private void init(){

		for(int i=0;i<50;i++){
			//处理请求
			redisMessageUtils.sendMessage("接收频道名称", UUID.randomUUID().toString());
		}
	}
相关推荐
庞轩px5 分钟前
内存区域的演进与直接内存——JVM性能优化的权衡艺术
java·jvm·笔记·性能优化
编码忘我20 分钟前
java多线程安全集合
java
悟空码字25 分钟前
滑块拼图验证:SpringBoot完整实现+轨迹验证+Redis分布式方案
java·spring boot·后端
编码忘我26 分钟前
java类加载器及tomcat为什么不用双亲委派
java
MegaDataFlowers1 小时前
快速上手Spring
java·后端·spring
小江的记录本1 小时前
【MyBatis-Plus】Spring Boot + MyBatis-Plus 进行各种数据库操作(附完整 CRUD 项目代码示例)
java·前端·数据库·spring boot·后端·sql·mybatis
左左右右左右摇晃1 小时前
Java 笔记--OOM产生原因以及解决方法
java·笔记
大傻^1 小时前
Spring AI Alibaba Function Calling:外部工具集成与业务函数注册
java·人工智能·后端·spring·springai·springaialibaba
逆境不可逃1 小时前
LeetCode 热题 100 之 33. 搜索旋转排序数组 153. 寻找旋转排序数组中的最小值 4. 寻找两个正序数组的中位数
java·开发语言·数据结构·算法·leetcode·职场和发展
码界奇点1 小时前
基于Spring Boot的医院药品管理系统设计与实现
java·spring boot·后端·车载系统·毕业设计·源代码管理