spring taskExecutor redis redisMessageListenerContailner jvm 线程优化

背景:

测试工程师给系统做压力测试,发现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>


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值