使用具有hikari cp的多个数据库时,multitenacy配置出现问题db峰值中的连接数

5hcedyr0  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(266)

在我们的应用程序中,我们有不同的房间与单独的数据库相关联。因此,我们使用了此配置,但无法控制池大小,每次进行db调用时,池大小都会不断增加:
java:1.8 hikaricp:3.4.5 hibernate核心:4.3.6.最终hibernate hikari:5.4.10.最终项目配置:spring mvc
hibernate-context.xml:

`<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    <property name="driverClassName" value="${sqlserver.jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${sqlserver.jdbc.url}"/>
    <property name="username" value="sa"/>
    <property name="password" value="Content151"/>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    <constructor-arg ref="hikariConfig" />
</bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
         <property name="packagesToScan" value="com.computhink.entity" />
                <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
                <prop key="hibernate.id.new_generator_mappings">true</prop>
                    <prop key="hibernate.multiTenancy">DATABASE</prop>
                <prop key="hibernate.tenant_identifier_resolver">com.computhink.service.CurrentTenantIdentifierResolverImpl</prop> 
                <prop key="hibernate.multi_tenant_connection_provider">com.computhink.service.MultiTenantConnectionProviderImpl</prop> 

            </props>
        </property>
        <!-- <property name="configLocation" value="WEB-INF/hibernate.cfg.xml" /> -->
    </bean>

    <tx:annotation-driven />

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
         <property name="autodetectDataSource" value="false"/>  
    </bean>
`

多租户连接提供程序模板:

public class MultiTenantConnectionProviderImpl extends 
    AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
    private static final long serialVersionUID = 6241633589847209550 L;

    private static final Logger logger = 
    LoggerFactory.getLogger(MultiTenantConnectionProviderImpl.class);
    private HikariDataSource defaultDataSource;
    ReadSqlServerproperties rssp = new ReadSqlServerproperties();
    RoomAndLoginDetailsService roomDetailsService = new RoomAndLoginDetailsServiceImpl();

    //ReadOracleProperties oraclepropvalue=new ReadOracleProperties();

    public MultiTenantConnectionProviderImpl() {
        ReadProperties sqlserverprop = rssp.getSqlServerProp();
        String durl = sqlserverprop.getPropurl();
        String dDriver = sqlserverprop.getProDriver();
        String duser = sqlserverprop.getProuser();
        String dpassword = sqlserverprop.getPropassword();
        String schemaname = sqlserverprop.getSchemaname();
        HikariConfig hikaConfig = new HikariConfig();
        hikaConfig.setPoolName("test");
        hikaConfig.setJdbcUrl(durl);
        //username
        hikaConfig.setUsername(duser);
        //password
        hikaConfig.setPassword(dpassword);
        //driver class name
        hikaConfig.setDriverClassName(dDriver);
        // Information about the pool
        //pool name. This is optional you don't have to do it.
        //the maximum connection which can be created by or resides in the pool
        hikaConfig.setMaximumPoolSize(5);
        //how much time a user can wait to get a connection from the pool.
        //if it exceeds the time limit then a SQlException is thrown
        hikaConfig.setConnectionTimeout(Duration.ofSeconds(30).toMillis());
        //The maximum time a connection can sit idle in the pool.
        // If it exceeds the time limit it is removed form the pool.
        // If you don't want to retire the connections simply put 0.
        hikaConfig.setIdleTimeout(10000);
        hikaConfig.setMinimumIdle(2);
        hikaConfig.setMaxLifetime(30000);
        hikaConfig.setValidationTimeout(3000);
        hikaConfig.setLeakDetectionThreshold(5000);
        hikaConfig.addDataSourceProperty("cachePrepStmts", true);
        hikaConfig.addDataSourceProperty("prepStmtCacheSize", 256);
        hikaConfig.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
        hikaConfig.addDataSourceProperty("useServerPrepStmts", true);
        hikaConfig.addDataSourceProperty("cacheResultSetMetadata", true);
        hikaConfig.addDataSourceProperty("cacheServerConfiguration", true);
        hikaConfig.addDataSourceProperty("elideSetAutoCommits", true);
        hikaConfig.addDataSourceProperty("maintainTimeStats", false);
        defaultDataSource = new HikariDataSource(hikaConfig);

    }

    protected DataSource selectAnyDataSource() {
        return defaultDataSource;
    }

    protected HikariDataSource selectDataSource(String tenantIdentifier) {

        System.out.println("START MultiTenantConnectionProviderImpl.selectDataSource");
        HikariConfig hikaConfig = new HikariConfig();
        HikariDataSource hc = null;
        String roomName = tenantIdentifier;
        String returndbenginename = roomDetailsService.getRoomsDBvalue(roomName);
        DbDetails dbvalue = roomDetailsService.getDbDetails(roomName);
        String username = dbvalue.getDbUser();
        String password = dbvalue.getDbPassword();
        String dbhost = dbvalue.getDbHost();
        String dbport = dbvalue.getDbPort();
        String dbname = dbvalue.getDbName();
        String url = "jdbc:sqlserver://" + dbhost + ":" + dbport + ";DatabaseName=" + dbname +
            ";SelectMethod=direct;";
        if (roomName == "Local") {
            hc = defaultDataSource;
        } else {
            hikaConfig.setJdbcUrl(url);
            //username
            hikaConfig.setUsername(username);
            //password
            hikaConfig.setPassword(password);
            //driver class name
            hikaConfig.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            // Information about the pool
            //pool name. This is optional you don't have to do it.
            //the maximum connection which can be created by or resides in the pool
            hikaConfig.setMaximumPoolSize(10);
            //how much time a user can wait to get a connection from the pool.
            //if it exceeds the time limit then a SQlException is thrown
            hikaConfig.setConnectionTimeout(Duration.ofSeconds(30).toMillis());
            //The maximum time a connection can sit idle in the pool.
            // If it exceeds the time limit it is removed form the pool.
            // If you don't want to retire the connections simply put 0.
            hikaConfig.setIdleTimeout(10000);
            hikaConfig.setMinimumIdle(2);
            hikaConfig.setMaxLifetime(30000);
            hikaConfig.setValidationTimeout(3000);
            hikaConfig.setLeakDetectionThreshold(5000);
            hikaConfig.addDataSourceProperty("cachePrepStmts", true);
            hikaConfig.addDataSourceProperty("prepStmtCacheSize", 256);
            hikaConfig.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
            hikaConfig.addDataSourceProperty("useServerPrepStmts", true);
            hikaConfig.addDataSourceProperty("cacheResultSetMetadata", true);
            hikaConfig.addDataSourceProperty("cacheServerConfiguration", true);
            hikaConfig.addDataSourceProperty("elideSetAutoCommits", true);
            hikaConfig.addDataSourceProperty("maintainTimeStats", false);
            hc = new HikariDataSource(hikaConfig);
        }
        return hc;
    }
}

connections是每个db调用的db峰值:db connections status

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题