spring taskExecutor redis redisMessageListenerContailner jvm 线程优化

《框架封装 · Redis 事件监听》 企业实战开发中,事件监听的运用场景非常多,当某事件发生的时候,会触发某个响应处理,其主要优势体现在多负载实例的场景下。与前几篇博文《知识点扫盲 · 监听器 Listener》《后端程序猿 · 基于 Lettuce 实现缓存容错策略》提到的观察者模式、发布订阅模式等,有异曲同工之妙。本篇文章先介绍一下,框架封装人员如何处理事件监听场景,默认基于实现,下面以此技术加以说明。上文介绍了框架封装人员,如何处理事件监听逻辑,提供了一些思路分享。 阅读详情

背景:

测试工程师给系统做压力测试,发现JVM产生了大量的redisMessageListenerContainer线程,系统跑着跑着进程就被kill掉了


查看源码:

进入redisMessageListenerContainer 类打断点进去,查看内部代码

redisMessageListenerContainer.java

public void onMessage(Message message, byte[] pattern) {
		Collection<MessageListener> listeners = null;
		// if it's a pattern, disregard channel
		if (pattern != null && pattern.length > 0) {
			listeners = patternMapping.get(new ByteArrayWrapper(pattern));
		} else {
			pattern = null;
			// do channel matching first
			listeners = channelMapping.get(new ByteArrayWrapper(message.getChannel()));
		}
		if (!CollectionUtils.isEmpty(listeners)) {
			dispatchMessage(listeners, message, pattern);
		}
	}

}

	private void dispatchMessage(Collection<MessageListener> listeners, final Message message, final byte[] pattern) {
		final byte[] source = (pattern != null ? pattern.clone() : message.getChannel());
		for (final MessageListener messageListener : listeners) {
			taskExecutor.execute(new Runnable() {// 使用了线程池

				public void run() {
					processMessage(messageListener, message, source);
				}
			});
		}
	}

	// 测试工程师给系统做压力测试,发现JVM产生了大量的redisMessageListenerContainer线程,系统跑着跑着进程就被kill掉了
	public void afterPropertiesSet() {
		if (taskExecutor == null) {// 如果没有设置默认的使用的是SimpleAsyncaskExecutor,这是一个简单的执行器,并不有线程池功能
			manageExecutor = true;
			taskExecutor = createDefaultTaskExecutor();
		}
		if (subscriptionExecutor == null) {
			subscriptionExecutor = taskExecutor;
		}
		initialized = true;
	}

	protected TaskExecutor createDefaultTaskExecutor() {
		String threadNamePrefix = (beanName != null ? beanName + "-" : DEFAULT_THREAD_NAME_PREFIX);
		return new SimpleAsyncTaskExecutor(threadNamePrefix);
	}

RedisHttpSessionConfiguration.Java

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory, RedisOperationsSessionRepository messageListener) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        if(this.redisTaskExecutor != null) {
            container.setTaskExecutor(this.redisTaskExecutor);
        }

        if(this.redisSubscriptionExecutor != null) {
            container.setSubscriptionExecutor(this.redisSubscriptionExecutor);
        }

        container.addMessageListener(messageListener, Arrays.asList(new PatternTopic[]{new PatternTopic("__keyevent@*:del"), new PatternTopic("__keyevent@*:expired")}));
        container.addMessageListener(messageListener, Arrays.asList(new PatternTopic[]{new PatternTopic(messageListener.getSessionCreatedChannelPrefix() + "*")}));
        return container;
    }
    
    @Qualifier("springSessionRedisTaskExecutor")
    public void setRedisTaskExecutor(Executor redisTaskExecutor) {
        this.redisTaskExecutor = redisTaskExecutor;
    }

解决方案:

XML中添加一个redis线程池,问题解决

<bean id="springSessionRedisTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
		<!-- 核心线程数 -->
		<property name="corePoolSize" value="10" />
		<!-- 最大线程数 -->
		<property name="maxPoolSize" value="300" />
		<!-- 队列最大长度 -->
		<property name="queueCapacity" value="500" />
		<!-- 线程池维护线程所允许的空闲时间,默认为60s -->
		<property name="keepAliveSeconds" value="60" />
</bean>


Redis 失效监听Key 来源:https://blog.youkuaiyun.com/m0_37780228/article/details/88853493 1.失效监听需要修改redis的conf文件 - notify-keyspace-events "" 改为notify-keyspace-events Ex # K 键空间通知,以__keyspace@<db>__为前缀 # E 键事件通知,以__keysevent@<db>__为前缀 # g del , expipre , rena.. 阅读详情

相关推荐

解决Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程问题

主要介绍了解决Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程问题,需要的朋友可以参考下

Redis 消息订阅(MessageListener接口)

Redis 消息订阅

zhangjunli的博客 1万+

FOC电机控制中电流采样延迟补偿的原理和方法

摘要: FOC电机控制中,电流采样、计算与PWM更新存在固有延迟(约1.5个PWM周期),导致相位滞后,限制电流环带宽。主流补偿方法包括: 一阶前向预测法:基于历史电流值预测未来电流,抵消延迟,工程应用广泛; 相位超前补偿:通过s/z域校正器设计实现等效预测; 状态观测器法(如龙伯格观测器):通过电机模型闭环估计状态,兼具噪声抑制和参数辨识能力,但复杂度高。实际需注意参数敏感性、离散化精度及延迟时间校准,避免过补偿风险。一阶预测法因平衡效果与复杂度成为工业首选。

jifengzhiling的博客 2231

开发小记~

积沙成山

qq_41199502的博客 2321

光伏逆变器在环测试解决方案

光伏行业是利用太阳能光辐射将其转化为可用电能的行业。近年来,为应对气候变化和能源安全等挑战,全球对清洁能源的需求不断增长。太阳能作为最具潜力和可再生的能源之一,被视为替代传统化石能源的重要选择,光伏行业因此得到了迅猛发展,并在全球范围内得到了广泛应用。许多国家和地区都将光伏技术作为关键的能源发展方向。尤其是在新兴和发展中国家,光伏发电具有巨大的增长潜力,将成为未来市场竞争的重点。随着规模化生产的推进,光伏组件的制造成本不断降低。

shiwei0813的博客 959

医学图像可视化实战:ITK-SNAP与Python+SimpleITK双方案解析

本文深入解析了医学图像可视化的两大核心方案:ITK-SNAP与Python+SimpleITK。ITK-SNAP作为专业无损浏览器,是数据探索与分析的必备工具;而Python+SimpleITK方案则提供了自动化处理能力,但需注意将.nii.gz数据转换为JPG等格式时的信息损失。文章通过实战对比,为医学影像处理者提供了清晰的选择指南与避坑建议。

ol789012的博客 490

#Redis问题排查#Connection failure occurred

本文提供了服务和配置文件两个角度的解决方案,大家有什么好的方案吗,请在评论区多多指教。

NVG_Haru的博客 7141

RK3588多路MIPI摄像头采集与WiFi低延迟传输实战指南

本文详细介绍了基于RK3588平台实现多路MIPI摄像头同步采集并通过WiFi进行低延迟传输的完整实战方案。文章深入剖析了从V4L2驱动配置、多线程采集、环形缓冲区设计到UDP网络传输优化的核心技术,旨在帮助开发者在工业检测、智能安防等场景下构建高并发、高实时性的视频流系统,实现端到端延迟控制在100毫秒以内的目标。

tensor9flow的博客 786

springboot-redis-messageListener

主要实现两个功能1.过期事件监听 KeyspaceEventMessageListener2.发布订阅 RedisMeaasgeListener DispatchMessageListener MessagelistenerAdapter。

weixin_39523456的博客 3483

在 NVIDIA Orin (JetPack 6.0) 上配置 PyTorch 2.4 + Torchvision 0.19 的完整避坑指南

本文提供在NVIDIA Jetson Orin设备上,基于JetPack 6.0系统配置PyTorch 2.4与Torchvision 0.19环境的完整指南。通过使用Miniconda环境隔离、安装特定版本PyTorch夜间构建版、编译匹配的Torchvision源码等步骤,解决版本不匹配、CUDA支持等常见问题,确保AI开发环境稳定可用。

weixin_29179311的博客 363

SDM660电源部分配置:

SDM660电源部分配置: Panel power supplies 1、Reference power supplies Description Name Regulator Voltage (V) Panel power supply 0 vddio PMIC 660/L11 1.8 Panel power supply 1 Lab PMIC 660/lab 4.6 Panel power s...

weixin_41811215的博客 4728

Redis 发布订阅MessageListener

redis 发布订阅管理

qq_39042827的博客 1383

PCL 法线定向【2025最新版】

几种法线定向方法的PCL代码实现。

点云侠的博客 2803

redis订阅mysql_redis发布订阅客户端报错

实例基础信息:redis版本:redis-cli 3.2.5架构:传统主从架构背景一天开发人员通过kibana查看tomcat日志时,发现以下错误RedisMessageListenerContainer 643 - Connection failure occurred. Restarting subscription task after 5000 msimage.png-问题分析1)百度查看...

weixin_33174392的博客 870

【ARM CoreLink 系列 5.3 -- CI-700 SLC memory 系统组件详细介绍】

在 CI-700 系统级缓存(SLC)内存系统中,HN-F 节点负责管理缓存一致性和数据传输。每个 HN-F 节点可以发送三种类型的 Snoop 请求,以确保系统中多核处理器和缓存之间的一致性。CI-700 中的系统级缓存(SLC)内存系统通过 HN-F 节点支持 TrustZone® 技术。以下是 CI-700 支持的 SN 类型以及配置方法的简要介绍。ARM CI-700 系统级缓存(SLC)是一个分布式、主要排他性(mostly exclusive) 的最后一级缓存,集成在 HN-F 节点内。

CodingCos的博客 897

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

ERROR o.s.d.redis.listener.RedisMessageListenerContainer

在运行eclipse项目的时候,有时候会遇到这样的报错项目没有办法登录。 ERROR o.s.d.redis.listener.RedisMessageListenerContainer - Connection failure occurred. Restarting subscription task after 500...

祈澈菇凉 6891

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

redis订阅关闭异常解决

应用程序模块订阅redis运行一段时间出现一直重连Redis服务,日志如下: [2015-12-24 08:30:17,307] ERROR listener.RedisMessageListenerContainer: Connection failure occurred. Restarting subscription task after 5000 ms [2015-12-24 0

yjh314的专栏 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

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

redis springboot 消息订阅发布

可爱猪猪 906

Redis键通知(事件通知)

Redis键通知(事件通知) 通常,对于Redis这款中间件,最多的应该是作为缓存来使用,比较好的做法是会给Redis中的key设置一个过期时间,过期之后自动删除。那么,我们可能会有这样的需求,如果一个key被删除了,或者过期了,能否通知使用redis的应用程序呢,其实是有方法的。 从Redis:2.8.0开始,提供了键空间通知的功能,详见官方文档Redis Keyspace Notifications - Redis 。原理就是基于Redis的PUB/SUB机制,当键被发生了某种操作时,Redis会往特定

carbuser_xl的博客 1422

redis 高级功能,过期事件监听

一、前言: 不谈应用场景的技术都是道听途说; 二、应用场景 1.1 需求一: 一个交易系统里面有一个价格提醒的功能,用户可以设置一组价格并设置一个周期,后台需要在交易的时间内进行价格扫描一旦触发用户设置的价格的周期就需要下发消息提醒给用户,提醒用户交易做单; 具体要求如下:交易系统都需要考虑实时性,所以后台的扫描周期为2s,用户量为公司所...

weixin_30845171的博客 1398

Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程

待解决的问题 Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程 解决办法 为spring session添加springSessionRedisTaskExecutor线程池。 /** * 用于spring session,防止每次创建一个线程 * @return */ @Bean public Threa...

weixin_30443075的博客 1732

Springboot 配置redis连接池

SpringBoot2.0默认采用Lettuce客户端来连接Redis服务端的.默认是不使用连接池的,只有配置 redis.lettuce.pool下的属性的时候才可以使用到redis连接池。 导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <arti...

liming19890713的专栏 1876

ERROR o.s.d.redis.listener.

在运行eclipse项目的时候,有时候会遇到这样的报错项目没有办法登录。 ERROR o.s.d.redis.listener.RedisMessageListenerContainer - Connection failure occurred. Restarting subscription task after 5000 ms 打开eclipse项目后台,可以看到报错如下所示 页...

qq_38822390的博客 1854

RedisMessageListenerContainer 监听redis的key的变化

通过 onMessage 方法拿到消息后,自行处理,写入我们的处理逻辑。@Component@Slf4j@Autowired@Autowired/*** 发布 事件* @param message 监听key的操作类型 主要是设值和过期。* @param bytes 监听的主题*/@Overridelog.info("收到key设值(更新)的消息:操作{},redisKey={}", key, redisKey);//查询//把redis的分隔符:替换成 mqtt的分隔符/

qq_43513957的博客 4175

idea启动项目redis报错Connection failure occurred. Restarting subscription task after 5000 ms

idea导入项目之后启动,报错: Connection failure occurred. Restarting subscription task after 5000 ms 我在网上搜的都是说: 缓存已经超出redis服务所规定的订阅缓存限制值,查看redis.conf配置文件。 client-output-buffer-limitpubsub32mb8mb60 # Redis订阅客户端订阅buffer超过32M或持续60秒超过8M,订阅立即被关闭!解决改问题把限制值调大即可解...

weixin_43560656的博客 2万+

Redis实现消息队列

前言 Redis可以通过发布订阅模式、轮询机制实现消息队列。 由于没有消息持久化与 ACK 的保证,所以,Redis 的发布订阅功能并不可靠。这也就导致了它的应用场景很有限,建议用于实时与可靠性要求不高的场景。 一、Redis发布订阅 1.原理 服务器中维护着一个pubsub_channels字典,所有的频道和订阅关系都存储在这里。字典的键为频道的名称,而值为订阅频道的客户端链表。 1. 当有新的客户端订阅某个频道时,会发生两种情况中的一种: (1)如果频道已经存在,则新的客户端会添加到pub

分享不仅为了他人,同时也为了自己 2059
上一篇: Intellij IDEA GIT 分支合并冲突
下一篇: AtomicInteger 理解
javaee_ssh
博客等级 码龄18年 42粉丝 42原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值