Jenkins 在部署 SpringMVC JPA webapp MySQL 连接未释放 HikariCP
Jenkins at deploy of a SpringMVC JPA webapp MySQL connections not freed HikariCP
环境: Ubuntu 14.04.4
开发中的应用详情: Spring 4.2.5.RELEASE MVC webapp, MySQL with 151 + 1 MAX_CONNECTIONS, Hibernate,HikariCP 作为数据源,每个池 20 个连接,1 个池。
自动化部署工具:Jenkins
部署容器: Tomcat 7
先决条件:
1. 应用程序已经启动并运行,可通过网络访问。
用例:
1.登录到mysql命令行并执行:show processlist;
2. 在命令行中观察 20 个连接 + 1 个你的连接。
3. 在 Jenkins 中触发新构建,并等待将新的 *.war 部署到 tomcat
4.执行:显示进程列表;在 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;
}
似乎连接没有释放,即使在重新部署应用程序之后也是如此。有什么想法吗?
最后做了以下事情:
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();
}
}
现在一切都按预期进行,即使经过几次 deploy/re-deploy 操作!
环境: Ubuntu 14.04.4
开发中的应用详情: Spring 4.2.5.RELEASE MVC webapp, MySQL with 151 + 1 MAX_CONNECTIONS, Hibernate,HikariCP 作为数据源,每个池 20 个连接,1 个池。
自动化部署工具:Jenkins
部署容器: Tomcat 7
先决条件:
1. 应用程序已经启动并运行,可通过网络访问。
用例:
1.登录到mysql命令行并执行:show processlist;
2. 在命令行中观察 20 个连接 + 1 个你的连接。
3. 在 Jenkins 中触发新构建,并等待将新的 *.war 部署到 tomcat
4.执行:显示进程列表;在 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;
}
似乎连接没有释放,即使在重新部署应用程序之后也是如此。有什么想法吗?
最后做了以下事情:
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();
}
}
现在一切都按预期进行,即使经过几次 deploy/re-deploy 操作!