【问题标题】:HikariCP Connection pooling in multi tenant application多租户应用程序中的 HikariCP 连接池
【发布时间】:2021-09-07 11:35:09
【问题描述】:

我在我的多租户应用程序中使用 HikariCP:-

private Map<Object, Object> targetDataSources = new HashMap<>();
AbstractRoutingDataSource dataSource = new TenantAwareRoutingSource();

public Object insertTenants(String tenantName, String dataSource,String url, String user, String password) throws Exception {
    targetDataSources.put(tenantName, buildDataSource(dataSource,url,user,password));
    dataSource.setTargetDataSources(targetDataSources);
    dataSource.afterPropertiesSet();
    return dataSource;
}

int i = 0;
private DataSource buildDataSource(String dataSource, String url, String user, String password) {
    HikariDataSource dataSource = new HikariDataSource();
    dataSource.setInitializationFailTimeout(0);
    dataSource.setMinimumIdle(1);
    dataSource.setPoolName("pool ->>  " + i);
    dataSource.setMaximumPoolSize(1);
    dataSource.setIdleTimeout(300000);
    dataSource.setMaxLifetime(30000);
    dataSource.setConnectionTimeout(60000);
    dataSource.setDataSourceClassName(dataSource);
    dataSource.addDataSourceProperty("url", url);
    dataSource.addDataSourceProperty("user", user);
    dataSource.addDataSourceProperty("password", password);
    i++;
    return dataSource;
}

以上代码允许在应用程序运行时创建数据源。

对于每个数据源,我正在创建新的池名称,但在调试模式下,我只能看到第一个池(即池 ->> 1)

2021-09-07 16:32:39.580 DEBUG 13360 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool        : pool ->>  1 - Added connection org.postgresql.jdbc.PgConnection@50c0f9ec
2021-09-07 16:32:39.580 DEBUG 13360 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool        : pool ->>  1 - After adding stats (total=5, active=0, idle=5, waiting=0)
2

当我插入新租户和尝试访问新的 tanant db 时,我可以访问它,但我无法在调试状态下看到该池名称(即 pool ->> 2)仍然显示池->> 1 中的

如何在调试器中查看其他池的详细信息。

任何建议都会有所帮助。

为每个租户创建一个新池是个好主意吗?

【问题讨论】:

    标签: java hikaricp


    【解决方案1】:

    我没有“解决方案”,但有一些提示,希望对您有所帮助。

    对于您的问题:我不知道您的设置,但如果每个租户都有自己的数据库,那么分离的连接池很有用。

    但是你做的方式并不是最好的。你的int i = 0 字段感觉很hacky。这是另一种方法:

    // it is possible, that the concurrent-hash-map will solve your problem
    private Map<String, DataSource> targetDataSources = new ConcurrentHashMap<>();
    
    AbstractRoutingDataSource dataSource = new TenantAwareRoutingSource();
    
    public DataSource insertTenants(String tenantName,
                                    String dataSource,
                                    String url, 
                                    String user,
                                    String password) throws Exception {
    
        var dataSource = buildDataSource(datasource, "pool@" + tenantName, url, user, password);
        targetDataSources.put(tenantName, dataSource);
    
        // I think that the problem might be here
        // All docs I found say that the tenants-map should be inserted with all tenants
        dataSource.setTargetDataSources(targetDataSources);
    
    
        dataSource.afterPropertiesSet();
        return dataSource;
    }
    
    private DataSource buildDataSource(String dataSource,
                                       String poolName,
                                       String url, 
                                       String user, 
                                       String password) {
    
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setInitializationFailTimeout(0);
        dataSource.setMinimumIdle(1);
        dataSource.setPoolName(poolName);
        dataSource.setMaximumPoolSize(1);
        dataSource.setIdleTimeout(300000);
        dataSource.setMaxLifetime(30000);
        dataSource.setConnectionTimeout(60000);
        dataSource.setDataSourceClassName(dataSource);
        dataSource.addDataSourceProperty("url", url);
        dataSource.addDataSourceProperty("user", user);
        dataSource.addDataSourceProperty("password", password);
        
        return dataSource;
    }
    

    也许它会有所帮助,当您针对这样的示例进行定位时:https://www.bytefish.de/blog/spring_boot_multitenancy.html

    【讨论】:

    • 谢谢。但我更注重功能。但你的建议在我的情况下不起作用....
    【解决方案2】:

    您需要使用连接配置详细信息创建 HikariConfig 对象,并在创建 HikariDatasource 时传递该信息。

    在 HikariDataconfig 部分尝试使用 HikariConfig 的 set 方法而不是 addDataSourceProperty() 添加 url、用户名和密码

    这对我有用,并且能够为每个租户创建单独的池。

    private DataSource buildDataSource(String dataSource,
                                   String poolName,
                                   String url, 
                                   String user, 
                                   String password) {
    
               HikariConfig hikariConfig = new HikariConfig();               
               hikariConfig.setInitializationFailTimeout(0);
               hikariConfig.setMinimumIdle(1);
               hikariConfig.setPoolName(poolName);
               hikariConfig.setMaximumPoolSize(1);
               hikariConfig.setIdleTimeout(300000);
               hikariConfig.setMaxLifetime(30000);
               hikariConfig.setConnectionTimeout(60000);
               hikariConfig.setDataSourceClassName(dataSource);
               hikariConfig.setJdbcUrl(url);
               hikariConfig.setUsername(user);
               hikariConfig.setPassword(password);    
               HikariDataSource dataSource = new HikariDataSource(hikariConfig);
               return dataSource;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-26
      • 2019-08-05
      • 2014-02-09
      • 2019-12-16
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多