国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

解決Spring session(redis存儲方式)監聽導致創建大量redisMessageListenerContailner-X線程問題

2024-07-14 08:42:13
字體:
來源:轉載
供稿:網友

待解決的問題

Spring session(redis存儲方式)監聽導致創建大量redisMessageListenerContailner-X線程

解決辦法

為spring session添加springSessionRedisTaskExecutor線程池。

/** * 用于spring session,防止每次創建一個線程 * @return */@Beanpublic ThreadPoolTaskExecutor springSessionRedisTaskExecutor(){  ThreadPoolTaskExecutor springSessionRedisTaskExecutor = new ThreadPoolTaskExecutor();  springSessionRedisTaskExecutor.setCorePoolSize(8);  springSessionRedisTaskExecutor.setMaxPoolSize(16);  springSessionRedisTaskExecutor.setKeepAliveSeconds(10);  springSessionRedisTaskExecutor.setQueueCapacity(1000);  springSessionRedisTaskExecutor.setThreadNamePrefix("Spring session redis executor thread: ");  return springSessionRedisTaskExecutor;}

原因

在Spring Session(redis)的配置類源碼中(RedisHttpSessionConfiguration):

@Autowired(  required = false  //該處理監聽的線程池不是必須的,如果不自定義默認將使用SimpleAsyncTaskExecutor線程池)@Qualifier("springSessionRedisTaskExecutor")public void setRedisTaskExecutor(Executor redisTaskExecutor) {  this.redisTaskExecutor = redisTaskExecutor;}

springSessionRedisTaskExecutor不是必須的,如果不自定義則spring默認將使用SimpleAsyncTaskExecutor線程池。

題外話

SimpleAsyncTaskExecutor:每次都將創建新的線程(說是“線程池”,其實并非真正的池化,但它可以設置最大并發線程數量。)

@EnableAsync開啟異步方法,背后默認使用的就是這個線程池。使用異步方法時如果業務場景存在頻繁的調用(該異步方法),請自定義線程池,以防止頻繁創建線程導致的性能消耗。如果該異步方法存在阻塞的情況,又調用量大,注意有可能導致OOM(線程還未結束,又增加了更多的線程,最后導致內存溢出)。@Async注解可以選擇使用自定義線程池。

它創建了SimpleAsyncTaskExecutor

說回RedisHttpSessionConfiguration,我們接著看:

@Beanpublic RedisMessageListenerContainer redisMessageListenerContainer() {  RedisMessageListenerContainer container = new RedisMessageListenerContainer();  container.setConnectionFactory(this.redisConnectionFactory);  if (this.redisTaskExecutor != null) {    container.setTaskExecutor(this.redisTaskExecutor);  }  if (this.redisSubscriptionExecutor != null) {    container.setSubscriptionExecutor(this.redisSubscriptionExecutor);  }  container.addMessageListener(this.sessionRepository(), Arrays.asList(new PatternTopic("__keyevent@*:del"), new PatternTopic("__keyevent@*:expired")));  container.addMessageListener(this.sessionRepository(), Collections.singletonList(new PatternTopic(this.sessionRepository().getSessionCreatedChannelPrefix() + "*")));  return container;}RedisMessageListenerContainer正是處理監聽的類,RedisMessageListenerContainer設置了不為空的redisTaskExecutor,因為spring session默認沒有配置該Executor,那RedisMessageListenerContainer在處理監聽時怎么使用線程呢?我們接著看RedisMessageListenerContainer的源碼:public void afterPropertiesSet() {  if (this.taskExecutor == null) {    this.manageExecutor = true;    this.taskExecutor = this.createDefaultTaskExecutor();  }  if (this.subscriptionExecutor == null) {    this.subscriptionExecutor = this.taskExecutor;  }  this.initialized = true;}protected TaskExecutor createDefaultTaskExecutor() {  String threadNamePrefix = this.beanName != null ? this.beanName + "-" : DEFAULT_THREAD_NAME_PREFIX;  return new SimpleAsyncTaskExecutor(threadNamePrefix);}

afterPropertiesSet()這個方法熟悉吧,這個方法將在所有的屬性被初始化后調用(InitializingBean接口細節這里不再贅述)。

 所以如果用戶沒有定義springSessionRedisTaskExecutor,Spring session將調用createDefaultTaskExecutor()方法創建SimpleAsyncTaskExecutor線程池。而這個“線程池”處理任務時每次都創建新的線程。所以你會發現很多個redisMessageListenerContailner-X線程。

總結

以上所述是小編給大家介紹的解決Spring session(redis存儲方式)監聽導致創建大量redisMessageListenerContailner-X線程問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 桐庐县| 罗平县| 历史| 汾西县| 桐乡市| 桐梓县| 绥宁县| 长乐市| 宁德市| 湄潭县| 昌宁县| 钦州市| 南木林县| 伊金霍洛旗| 石城县| 夏河县| 定兴县| 安丘市| 松阳县| 新疆| 张家口市| 伊金霍洛旗| 石嘴山市| 亚东县| 宜兰县| 嵊州市| 郓城县| 沙洋县| 四川省| 南宁市| 郑州市| 大埔区| 水城县| 鸡西市| 仁布县| 沁水县| 盐城市| 黑龙江省| 东乌珠穆沁旗| 高陵县| 辛集市|