前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解决:[HikariPool-1 housekeeper] but has failed to stop it. This is very likely to create a memory leak

解决:[HikariPool-1 housekeeper] but has failed to stop it. This is very likely to create a memory leak

作者头像
北漂的我
发布2024-04-25 14:56:43
1310
发布2024-04-25 14:56:43
举报
文章被收录于专栏:北漂的我北漂的我

最近在用 SpringBoot 2.7.3 写 demo 的时候发现, 如果请求查询数据库之后, 停止服务时就会报一个警告, 好像说是 HikariPool 资源没有释放

代码语言:javascript
复制
[HikariPool-1 housekeeper] but has failed to stop it. This is very likely to create a memory leak

其实看日志发现, HikariPool 资源最后是释放了的, 只不过是稍微晚了一点

网上关于这个问题的解决方案很少, 难道只有我遇到了么. 是我哪里配置的不好, 导致的吗? 我写的 demo 是最简单的 SpringBoot + mybatis + mysql 经过各种查资料各种研究, 要解决这个问题, 个人觉得应该在内置 Tomcat 优雅停机之后才马上关闭数据源, 参考了内置 tomcat 的 GracefulShutdown 的代码

代码语言:javascript
复制
package com.scsoft.demo3.config;

import org.apache.catalina.Container;
import org.apache.catalina.Engine;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;

import com.zaxxer.hikari.HikariDataSource;

@Component
public class ShutdownHook implements ApplicationListener<ContextClosedEvent> {

	@Autowired
	private ServletWebServerApplicationContext servletWebServerApplicationContext;

	@Override
	public void onApplicationEvent(ContextClosedEvent event) {
		Engine engine = ((TomcatWebServer) servletWebServerApplicationContext.getWebServer()).getTomcat().getEngine();
		for (Container host : engine.findChildren()) {
			for (Container context : host.findChildren()) {
				while (isActive(context)) {
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						throw new RuntimeException(e);
					}
				}
			}
		}
//		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
//		System.out.println("ContextClosedEvent 调用" + sdf.format(new Date()));
		ApplicationContext applicationContext = event.getApplicationContext();
		HikariDataSource hikariDataSource = applicationContext.getBean(HikariDataSource.class);
		hikariDataSource.close();
	}

	private boolean isActive(Container context) {
		try {
			if (((StandardContext) context).getInProgressAsyncCount() > 0) {
				return true;
			}
			for (Container wrapper : context.findChildren()) {
				if (((StandardWrapper) wrapper).getCountAllocated() > 0) {
					return true;
				}
			}
			return false;
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}
}

以上代码是参考 org.springframework.boot.web.embedded.tomcat.GracefulShutdown 类中的 doShutdown 优雅停机方法

这个问题的解决研究了一天, 如果是我哪里配置不对导致的, 欢迎指点.

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com