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

时间:2016-09-28 16:08:41

标签: java mysql spring jenkins hikaricp

环境: Ubuntu 14.04.4

应用程序开发细节:Spring 4.2.5.RELEASE MVC webapp,MySQL有151 + 1 MAX_CONNECTIONS,Hibernate,HikariCP作为数据源,每个池有20个连接,1个池。

自动部署工具: Jenkins

部署容器: Tomcat 7

先决条件:
1.应用程序已经启动并正常运行,可通过网络访问。

使用情况:
1.登录mysql命令行并执行:show processlist;
2.在命令行中观察20个连接+ 1,你的 3.在Jenkins中触发新构建,并等待新的.war变为tomcat的部署 执行:show processlist;在mysql命令行中 5.在命令行中观察40个连接+ 1,你的 6.观察到MAX_CONNECTIONS + 1之间的连接增加,之后Jenkins无法构建,因为需要数据库失败的单元测试。

预期: 访问应用程序时最多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 个答案:

答案 0 :(得分:0)

结束以下操作:

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();
}

}

现在,即使经过多次部署/重新部署操作,一切都按预期工作!