【发布时间】:2017-03-22 10:31:40
【问题描述】:
我正在使用AbstractRoutingDataSource 在我的应用程序中创建多租户。我注意到,在从我的 IDE 重新部署了几次 webapp 之后,我最终得到了 MySQL 错误“连接太多”。
经过进一步调查,我发现当我运行MySQL命令show processlist;时,我看到每次部署后打开的连接量增加了10,这可能意味着连接池在某个地方仍然存在。
在我使用AbstractRoutingDataSource 之前,我使用了默认的spring 数据源配置(使用application.properties),它运行良好。
这里是多租户配置类:
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
/**
* Created by Alon Segal on 16/03/2017.
*/
@Configuration
public class MultitenantConfiguration {
@Autowired
private DataSourceProperties properties;
/**
* Defines the data source for the application
*
* @return
*/
@Bean
@ConfigurationProperties(
prefix = "spring.datasource"
)
public DataSource dataSource() {
//Creating datasources map "resolvedDataSources" here
MultitenantDataSource dataSource = new MultitenantDataSource();
dataSource.setDefaultTargetDataSource(defaultDataSource());
dataSource.setTargetDataSources(resolvedDataSources);
// Call this to finalize the initialization of the data source.
dataSource.afterPropertiesSet();
return dataSource;
}
/**
* Creates the default data source for the application
*
* @return
*/
private DataSource defaultDataSource() {
.
.
.
}
}
还有数据源类:
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* Created by Alon Segal on 16/03/2017.
*/
public class MultitenantDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return TenantContext.getCurrentTenant();
}
}
我也尝试使用@Bean(destroyMethod = "close"),但AbstractRoutingDataSource 上没有定义关闭方法。
我到处搜索,但找不到答案。有人可以帮我了解是什么阻止了连接池在重新部署之间被释放吗?
提前致谢。
【问题讨论】:
-
您的
resolvedDataSource应该关闭。显然,您并没有将它们创建为 spring bean,这意味着它们会挂起而不是关闭。要么使这些已解析的数据源成为小枝豆,以便 spring 可以关闭它,要么在您的MultitenantDataSource中实现一个 close 方法来关闭它们。 -
感谢@M.Denium 的回答。如何将它们创建为 Spring bean?它们是根据配置文件动态创建的..
-
那么在你的
MultitenantDataSource中创建一个close方法并关闭你连接到它的所有targetDataSources可能是最简单的。 -
为什么不使用池?像 hikari 或 apache
-
@ali 这并没有解决我的问题,但它还是有用的。我采用了明显更强大的 Hikari 连接池。
标签: java mysql spring hibernate spring-boot