- 出现CPU利用率异常了
- 原因:SpringSession的默认配置不合理导致
- 解决办法
- 小结
背景:出现异常了
发现应用的CPU利用率持续大于90%,且存在CPU热点。 查看监控,发现“线程创建销毁”指标不正常:
正常的应该是这样的:
创建线程是耗时耗资源的操作,一般都会使用线程池来。看上面的数据,同一个时间点,创建的线程数和销毁的线程数在同一个数据量级,很可能是new Thread方式创建的线程执行耗时较短的,然后马上被GC回收引发。不像是使用了线程池。
原来是你啊:springSessionRedisMessageListenerContailner-X
springSessionRedisMessageListenerContailner-X 线程是干什么的?
先来回顾一下SpringSession的事件驱动机制:
SpringSession基于Redis的Pub/Sub能力,通过RedisMessageListenerContainer来实现了Sesssion事件机制。 在spring-session-data-redis 2.5.6中, RedisMessageListenerContainer承载了三类事件: Session创建事件: [SessionCreatedEvent] Session删除事件: [SessionDeletedEvent] Session过期事件: [SessionExpiredEvent]
springSessionRedisMessageListenerContailner-X线程在SpringSession的事件机制是干活的。是worker线程。
org.springframework.session.data.redis.config.annotation.web.http. RedisHttpSessionConfiguration #springSessionRedisMessageListenerContainer
org.springframework.data.redis.listener. RedisMessageListenerContainer #afterPropertiesSet
org.springframework.data.redis.listener. RedisMessageListenerContainer #createDefaultTaskExecutor
org.springframework.data.redis.listener.RedisMessageListenerContainer#dispatchMessage
org.springframework.util.CustomizableThreadCreator#createThread
通过debug,问题已经搞清了:SpringSession的事件机制默认使用SimpleAsyncTaskExecutor来execute监听事件任务。 默认情况下,SimpleAsyncTaskExecutor通过new Thread来管理执行任务的worker线程。
怎么解决?
org.springframework.session.data.redis.config.annotation.web.http. RedisHttpSessionConfiguration #setRedisTaskExecutor
代码语言:javascript复制 /**
* 用于spring session,防止每次创建一个线程
*
* @return
*/
@Bean
public ThreadPoolTaskExecutor springSessionRedisTaskExecutor() {
ThreadPoolTaskExecutor springSessionRedisTaskExecutor = new ThreadPoolTaskExecutor();
springSessionRedisTaskExecutor.setCorePoolSize(30);
springSessionRedisTaskExecutor.setMaxPoolSize(100);
springSessionRedisTaskExecutor.setKeepAliveSeconds(60);
springSessionRedisTaskExecutor.setQueueCapacity(1000);
springSessionRedisTaskExecutor.setDaemon(true);
springSessionRedisTaskExecutor.setThreadNamePrefix("s-s-e");
return springSessionRedisTaskExecutor;
}
Bean名必须是springSessionRedisTaskExecutor
将项目重新发版上线后,问题没有再出现。
小结
通过以上的分析和处理,我们成功地解决了SpringSession默认配置导致的CPU异常问题。这个过程中,我们深入理解了SpringSession的工作原理和配置方式,也学习了如何有效地解决CPU异常的问题。
总的来说,虽然这个问题给我们带来了一些困扰,但也让我们收获了很多。我们将继续努力,提高我们的技术能力和解决问题的能力,以便在未来的开发过程中,能够更好地应对各种问题。