Spring引导应用程序中的Liquibase保持10个连接打开

Spring引导应用程序中的Liquibase保持10个连接打开,spring,spring-boot,liquibase,Spring,Spring Boot,Liquibase,我正在使用Liquibase集成开发一个Spring引导应用程序来设置数据库。对于使用application.properties文件配置的数据库更改,我们使用不同的用户 liquibase.user=abc liquibase.password=xyz liquibase.url=jdbc:postgresql://something.eu-west-1.rds.amazonaws.com:5432/app?ApplicationName=${appName}-liquibase liquib

我正在使用Liquibase集成开发一个Spring引导应用程序来设置数据库。对于使用application.properties文件配置的数据库更改,我们使用不同的用户

liquibase.user=abc
liquibase.password=xyz
liquibase.url=jdbc:postgresql://something.eu-west-1.rds.amazonaws.com:5432/app?ApplicationName=${appName}-liquibase
liquibase.enabled=true
liquibase.contexts=dev,postgres
目前我们部署了3种不同的微服务,我们注意到,对于每个正在运行的实例,Liquibase都会打开10个连接,除非我们停止应用程序,否则它永远不会关闭这些连接。这基本上意味着在开发过程中,我们经常会遇到AmazonRDS实例的连接限制

目前,在开发过程中,74个活跃连接中有40个被Liquibase占用。如果我们想用它投入生产,为所有的微服务启用自动缩放功能,这意味着我们将不得不过度扩展数据库,以避免达到任何连接限制

有办法去吗

  • 告诉liquibase不要使用包含10个连接的连接池
  • 告诉liquibase停止或关闭连接

到目前为止,我还没有找到关于如何执行此操作的文档。

我不知道为什么liquibase不关闭连接,也许这是一个bug,您应该为此负责

要为liquibase设置连接池,您必须创建一个自定义数据源,并用
@liquibasestatasource
注释对其进行标记

相关问题提供了更多细节:


我不知道为什么liquibase不关闭连接,也许这是一个bug,你应该为此负责

要为liquibase设置连接池,您必须创建一个自定义数据源,并用
@liquibasestatasource
注释对其进行标记

相关问题提供了更多细节:


    • 感谢Slava的响应,我成功地解决了以下数据源配置类的问题

      @Configuration
      public class LiquibaseDataSourceConfiguration {
      
          private static final Logger LOG = LoggerFactory.getLogger(LiquibaseDataSourceConfiguration.class);
      
          @Autowired
          private LiquibaseDataSourceProperties liquibaseDataSourceProperties;
      
          @LiquibaseDataSource
          @Bean
          public DataSource liquibaseDataSource() {
              DataSource ds =  DataSourceBuilder.create()
                      .username(liquibaseDataSourceProperties.getUser())
                      .password(liquibaseDataSourceProperties.getPassword())
                      .url(liquibaseDataSourceProperties.getUrl())
                      .driverClassName(liquibaseDataSourceProperties.getDriver())
                      .build();
              if (ds instanceof org.apache.tomcat.jdbc.pool.DataSource) {
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setInitialSize(1);
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setMaxActive(2);
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setMaxAge(1000);
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setMinIdle(0);
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setMinEvictableIdleTimeMillis(60000);
              } else {
                  // warnings or exceptions, whatever you prefer
              }
      
              LOG.info("Initialized a datasource for {}", liquibaseDataSourceProperties.getUrl());
              return ds;
          }
      
      }
      
      属性的文档可以在Tomcat的网站上找到:

      • initialSize:启动池时创建的初始连接数
      • maxActive:可同时从此池分配的最大活动连接数
      • minIdle:池中应始终保持的最小已建立连接数
      • maxAge:保持此连接的时间(以毫秒为单位)。当一个连接返回到池中时,池将检查是否已达到现在的时间When connected>maxAge,如果是,它将关闭连接而不是将其返回到池中。默认值为0,这意味着连接将保持打开状态,并且在将连接返回到池时不会进行年龄检查
      • minEvictableIdleTimeMillis:对象在符合驱逐条件之前在池中处于空闲状态的最短时间

      因此,这似乎不是连接泄漏,这只是数据源的默认配置,如果使用专用数据源,这对于Liquibase来说不是最佳配置。如果liquibase数据源是您的主要数据源,我认为这不会是一个问题。

      感谢Slava的响应,我通过以下数据源配置类解决了这个问题

      @Configuration
      public class LiquibaseDataSourceConfiguration {
      
          private static final Logger LOG = LoggerFactory.getLogger(LiquibaseDataSourceConfiguration.class);
      
          @Autowired
          private LiquibaseDataSourceProperties liquibaseDataSourceProperties;
      
          @LiquibaseDataSource
          @Bean
          public DataSource liquibaseDataSource() {
              DataSource ds =  DataSourceBuilder.create()
                      .username(liquibaseDataSourceProperties.getUser())
                      .password(liquibaseDataSourceProperties.getPassword())
                      .url(liquibaseDataSourceProperties.getUrl())
                      .driverClassName(liquibaseDataSourceProperties.getDriver())
                      .build();
              if (ds instanceof org.apache.tomcat.jdbc.pool.DataSource) {
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setInitialSize(1);
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setMaxActive(2);
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setMaxAge(1000);
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setMinIdle(0);
                  ((org.apache.tomcat.jdbc.pool.DataSource) ds).setMinEvictableIdleTimeMillis(60000);
              } else {
                  // warnings or exceptions, whatever you prefer
              }
      
              LOG.info("Initialized a datasource for {}", liquibaseDataSourceProperties.getUrl());
              return ds;
          }
      
      }
      
      属性的文档可以在Tomcat的网站上找到:

      • initialSize:启动池时创建的初始连接数
      • maxActive:可同时从此池分配的最大活动连接数
      • minIdle:池中应始终保持的最小已建立连接数
      • maxAge:保持此连接的时间(以毫秒为单位)。当一个连接返回到池中时,池将检查是否已达到现在的时间When connected>maxAge,如果是,它将关闭连接而不是将其返回到池中。默认值为0,这意味着连接将保持打开状态,并且在将连接返回到池时不会进行年龄检查
      • minEvictableIdleTimeMillis:对象在符合驱逐条件之前在池中处于空闲状态的最短时间

      因此,这似乎不是连接泄漏,这只是数据源的默认配置,如果使用专用数据源,这对于Liquibase来说不是最佳配置。如果liquibase数据源是您的主要数据源,我认为这不会是一个问题。

      此连接池管理更改是在Spring Boot版本
      2.0.6.版本中引入的,并且仅在使用Spring Boot启动器时生效。有一个执行器端点(默认情况下启用),允许您获取Liquibase应用的更改集。为使其工作,Liquibase保持其数据库连接打开。您可以使用
      management.endpoint.liquibase.enabled=false禁用端点,在这种情况下,liquibase使用的连接池将在初始运行后关闭

      • 与此更改相关的GitHub问题:
      • 弹簧防尘套执行器(参见
        12.液化

      此连接池管理更改是在Spring Boot版本
      2.0.6.版本中引入的,仅在使用Spring Boot Actuator时生效。存在一个执行器端点(默认情况下启用)它允许您获取由Liquibase应用的更改集。为了实现此目的,Liquibase将保持其数据库连接处于打开状态。您可以使用
      management.endpoint.Liquibase.enabled=false来禁用端点,在这种情况下,Liquibase使用的连接池将在首次运行后关闭

      • 与此更改相关的GitHub问题:
      • 弹簧防尘套执行器(参见
        12.液化

      好的,这可能非常有趣,因为使用自定义数据源,我可以使用以下代码指定
      datasource.dbcp2.initial size=1
      ,我成功地将连接数减少到1。但是,尽管将最大使用时间配置为10秒