有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Jenkins在部署SpringMVC JPA webapp MySQL连接时未释放HikariCP

环境:Ubuntu 14.04.4

开发细节中的应用:Spring 4.2.5。发布MVC webapp、MySQL和151+1个MAX_连接、Hibernate、HikariCP作为数据源,每个池20个连接,1个池

自动部署工具:Jenkins

部署容器:Tomcat 7

先决条件:
1.应用程序已启动并正在运行,可通过web访问

用例:
1.登录mysql命令行并执行:show processlist
2.在命令行中观察20个连接+1
3.在Jenkins中触发新构建,并等待新*的部署。向雄猫宣战
4.执行:显示进程列表;在mysql命令行中
5.在命令行中观察40个连接+1
6.观察连接数增加到最大连接数+1,之后Jenkins无法构建,因为需要DB的单元测试失败

预期: 当应用程序被访问时,最多20个连接,如果应用程序空闲,则根本没有连接(这是我在本地开发Windows 8.1 Pro机器上观察到的行为)

HikariCP数据源详细信息:

@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean() {
    LocalContainerEntityManagerFactoryBean sessionFactory = new LocalContainerEntityManagerFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan("com.myapp");

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    sessionFactory.setJpaVendorAdapter(vendorAdapter);
    sessionFactory.setJpaProperties(hibernateProperties());

    return sessionFactory;
}

private DataSource dataSource() {

    final HikariDataSource ds = new HikariDataSource();
    ds.setMaximumPoolSize(20);
    ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
    ds.addDataSourceProperty("url", "jdbc:mysql://localhost/myapp");
    ds.addDataSourceProperty("user", "usr");
    ds.addDataSourceProperty("password", "pwd");
    ds.addDataSourceProperty("cachePrepStmts", true);
    ds.addDataSourceProperty("prepStmtCacheSize", 250);
    ds.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
    ds.addDataSourceProperty("useServerPrepStmts", true);

    return ds;
}

private Properties hibernateProperties() {
    final Properties properties = new Properties();
    properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    properties.put("hibernate.hbm2ddl.auto", "validate");
    properties.put("hibernate.implicit_naming_strategy", "legacy-jpa");
    return properties;
}

即使在重新部署应用程序之后,这些连接似乎也不会被释放。有什么想法吗


共 (1) 个答案

  1. # 1 楼答案

    最后做了以下几件事:

    public class MyLocalContainerEntityManagerFactoryBean extends LocalContainerEntityManagerFactoryBean {
    
    public static final LoggerWrapper logger = new LoggerWrapper(MyLocalContainerEntityManagerFactoryBean.class);
    
    @Override
    public void destroy() {
    
        logger.warning("Destroying MyLocalContainerEntityManagerFactoryBean!");
    
        DataSource ds = getDataSource();
        if(ds instanceof HikariDataSource) {
            HikariDataSource hds = (HikariDataSource)ds;
    
            logger.warning("Closing the Hikari data source!");
            hds.close();
        }
    
        super.destroy();
    }
    

    }

    现在,即使在执行了几次部署/重新部署操作之后,一切都按预期运行