环境: 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;
}
即使重新部署应用程序,似乎也没有释放连接。有什么想法吗?
答案 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();
}
}
现在,即使经过多次部署/重新部署操作,一切都按预期工作!