【问题标题】:Adding new DataSource in runtime在运行时添加新的数据源
【发布时间】:2015-08-03 17:12:53
【问题描述】:

我不是一个非常有经验的 Java 程序员,可能有非常简单的问题。在描述问题之前,让我先解释一下架构:

  1. 我们需要一个云端应用
  2. 我们有四个客户,每个客户都有自己的 MySQL 数据库实例(总共 4 个数据库)。这主要是出于政治和一些性能原因(某些读取最多需要 20 秒才能执行,每 1 或 2 秒执行一次 INSERT 语句)
  3. 该应用程序将在两个 VM 实例上运行,以实现故障转移和更好的性能,即。 DataSource 将是动态的,因为两个应用程序实例中的任何一个都可能以数据库实例之一为目标
  4. 我们计划为所有客户提供一个配置数据库,用作应用程序的内部存储库。我们在这里维护用户和其他配置、活动监控等

每当我们添加新客户时,应用程序不应该重新启动,因此配置数据库。在这个数据库中,我们计划为每个用户保留一个数据源,并在调用 RESTful 服务时执行查找(可以称为无状态数据源)。唯一要做的额外事情是添加新的 MySQL 实例。
我们使用的主要框架/工具有 java、Spring (JdbcTemplate)、HikariCP(JDBC 连接池)和 Tomcat。

我们有以下问题:

  1. 连接池和javax.sql.DataSource是什么关系,即。因为我们计划为每个 RESTful 方法调用重新创建 DataSource,这会破坏数据库 X 的现有连接池吗?
  2. 当在配置数据库中指定数据源时,在 Spring 中实现动态数据源的最佳方法是什么(我确实阅读了以下 link 解释在配置文件中定义的动态数据源,不支持在运行时添加新源)

亲切的问候
啊。

【问题讨论】:

    标签: java jdbc connection-pooling spring-jdbc


    【解决方案1】:

    连接池和javax.sql.DataSource是什么关系,即。因为我们计划为每个 RESTful 方法调用重新创建 DataSource,这会破坏数据库 X 的现有连接池吗?

    数据库连接池不一定是 JDBC 构造。相反,出现了 JDBC DB 连接池的各种实现。 Tomcat 可能不容易用于添加动态运行时数据源(我自己没有做过,所以不确定)。但是还有其他存在确实允许这样做。例如vibur是一个数据库连接池,允许用户在运行时添加DataSources。

    public DataSource createDataSourceWithStatementsCache() {
        ViburDBCPDataSource ds = new ViburDBCPDataSource();
    
        ds.setJdbcUrl("jdbc:hsqldb:mem:sakila;shutdown=false");
        ds.setUsername("sa");
        ds.setPassword("");
    
        ds.setPoolInitialSize(10);
        ds.setPoolMaxSize(100);
    
        ds.setConnectionIdleLimitInSeconds(30);
        ds.setTestConnectionQuery("isValid");
    
        ds.setLogQueryExecutionLongerThanMs(500);
        ds.setLogStackTraceForLongQueryExecution(true);
    
        ds.setStatementCacheMaxSize(200);
    
        ds.start();
        return ds;
    }   
    

    该方法来自 vibur website。我过去曾在性能关键型应用程序中使用它们并取得了巨大成功。连接池可能会检测到重复项,但如果不是,您可以向该方法添加检查某种 HashSet 以查看具有该用户名/pw/connectionString 的 DataSource 是否已经存在。

    当在配置数据库中指定数据源时,在 Spring 中实现动态数据源的最佳方法是什么(我确实阅读了以下链接,解释了配置文件中定义的动态数据源,不支持在运行时添加新源)

    过去,我从事过一个必须使用运行时数据源的项目。这并不难。我们就是这样做的。您基本上只需要一个包含连接字符串、驱动程序(如果需要多个数据库并且动态加载驱动程序,对您的情况可能不是问题)和凭据的表。您可以使用更多属性(例如连接数等)来增强您的表格。那么您所需要的只是一个可用于查找此信息的 ID。

    当请求进入时,您可以检查从请求中获取数据库 ID 或从缓存源或任何地方轮询它。然后使用该数据库 ID,您可以查找数据库连接信息并使用上述方法创建数据源。显然,您将使用缓存来避免 DB 调用……这些数据是相当静态的信息,不需要在每次请求时都检索。

    【讨论】:

      【解决方案2】:

      也许这会有所帮助:

      public static DataSource getDataSource() {
          ApplicationContext context = new ClassPathXmlApplicationContext("myContext.xml");
          return (DataSource) context.getBean("dataSource");
      }
      

      和 myContext.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ws="http://jax-ws.dev.java.net/spring/core"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xmlns:jee="http://www.springframework.org/schema/jee"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
             http://jax-ws.dev.java.net/spring/core
              http://jax-ws.dev.java.net/spring/core.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-3.0.xsd
              http://jax-ws.dev.java.net/spring/servlet
              http://jax-ws.dev.java.net/spring/servlet.xsd
             http://www.springframework.org/schema/jee
             http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
      
          <bean id="dataSource"
              class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
              <property name="url" value="" />
              <property name="username" value="" />
              <property name="password" value="" />
          </bean>
      
      </beans>
      

      【讨论】:

      • 这是一个没有池的过于简单的解决方案。当您使用相同的 url、用户和密码重新创建数据源时,内存中的现有池会发生什么?
      猜你喜欢
      • 2018-03-12
      • 2018-12-05
      • 2019-07-01
      • 2018-01-24
      • 2016-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      相关资源
      最近更新 更多