【问题标题】:Connection pool size with postgres r2dbc-poolpostgres r2dbc-pool 的连接池大小
【发布时间】:2019-09-17 09:26:56
【问题描述】:

我无法使用 spring-webflux 和 r2dbc(使用 r2dbc-pool 驱动程序0.8.0.M8)打开超过 10 个连接。我的配置如下:

@Configuration
public class PostgresConfig extends AbstractR2dbcConfiguration {

  @Override
  @Bean
  public ConnectionFactory connectionFactory() {
    ConnectionFactory connectionFactory = ConnectionFactories.get(ConnectionFactoryOptions.builder()
        .option(DRIVER, "pool")
        .option(PROTOCOL, "postgresql")
        .option(HOST, host)
        .option(USER, user)
        .option(PASSWORD, password)
        .option(DATABASE, database)
        .build());
    ConnectionPoolConfiguration configuration = ConnectionPoolConfiguration.builder(connectionFactory)
        .maxIdleTime(Duration.ofMinutes(30))
        .initialSize(initialSize)
        .maxSize(maxSize)
        .maxCreateConnectionTime(Duration.ofSeconds(1))
        .build();
    return new ConnectionPool(configuration);
  }
}

当我指定超过 10 个连接时,我会收到如下错误:

org.springframework.dao.DataAccessResourceFailureException: 
Failed to obtain R2DBC Connection; nested exception is 
java.util.concurrent.TimeoutException: 
Did not observe any item or terminal signal within 1000ms in 'lift' 
(and no fallback has been configured)
    at org.springframework.data.r2dbc.connectionfactory.ConnectionFactoryUtils
    .lambda$getConnection$0(ConnectionFactoryUtils.java:71)

此外,连接数保持与初始大小相同。未创建新连接。

【问题讨论】:

  • 也许你应该增加maxCreateConnectionTime呢?毕竟你已经超时了。

标签: java spring-webflux r2dbc


【解决方案1】:

Spring boot(至少 2.3.4)在由 properties/yaml 设置时对池大小有一个棘手的“陷阱”。如果您在数据库 url 中包含“pool”,那么设置的大小(初始大小或最大大小)将不会产生任何影响,并且将使用 r2dbc 池的默认值 10 和 10。

这是由于 ConnectionFactoryConfigurations.java 中的 PooledConnectionFactoryCondition 在 spring.r2dbc.pool.enabled=true 都失败时,如果 r2dbc-pool 依赖项位于类路径上,并且“池”是 @987654323 的一部分@属性。

来自 PooledConnectionFactoryCondition 文档:

检查是否请求了 ConnectionPool 的条件。这 如果池是通过配置选择加入并且 r2dbc url 不包含池相关选项,则条件匹配。

这又会导致 ConnectionPool bean 没有被创建。

跳过 r2dbc url 属性中的“pool”关键字并具有 r2dbc-pool 依赖项,然后您将获得正确配置的池。

【讨论】:

  • 这是一条非常重要的评论!我还使用spring.r2dbc.pool.enabled 属性和 URL 中的:pool: 遇到了这种歧义。但是,我得到了一个不同且非常奇特的结果——如果前面提到的PooledConnectionFactoryCondition 失败,那么无论如何都会创建连接池,但来自不同的源(即io.r2dbc.pool.PoolingConnectionFactoryProvider#create)。这看起来像 Spring Boot 可以基于 PooledConnectionFactoryCondition 创建一个连接池,但如果失败则将其创建委托给 io.r2dbc.pool.PoolingConnectionFactoryProvider.class
【解决方案2】:

好的,还应为ConnectionFactoryOptions 指定 MAX_SIZE。否则连接池大小仍为 10。

import static io.r2dbc.pool.PoolingConnectionFactoryProvider.MAX_SIZE;

    ConnectionFactory connectionFactory = ConnectionFactories.get(ConnectionFactoryOptions.builder()
        .option(DRIVER, "pool")
        .option(PROTOCOL, "postgresql")
        .option(HOST, host)
        .option(USER, user)
        .option(PASSWORD, password)
        .option(DATABASE, database)
        .option(MAX_SIZE, maxSize)
        .build());

【讨论】:

    【解决方案3】:

    请注意,您可以使用发布版本 0.8.4.RELEASE(这是最新的)https://mvnrepository.com/artifact/io.r2dbc/r2dbc-postgresql/0.8.4.RELEASE,它不需要您实例化 ConnectionFactory

    【讨论】:

      【解决方案4】:

      如果你使用的是 spring-boot-starter-data-r2dbc,那么 min 和 max 可以在 application.properties 中配置

      spring.r2dbc.pool.initialSize=2
      spring.r2dbc.pool.maxSize=2
      

      org.springframework.boot.autoconfigure.r2dbc.R2dbcProperties

      【讨论】:

        【解决方案5】:

        以下是我对spring-boot-starter-data-r2dbc 的配置检查是否对您有帮助:

        spring:
          r2dbc:
            url: r2dbc:postgresql://127.0.0.1:5432/test?schema=public
            username: postgres
            password: postgres
            pool:
              name: TEST-POOL
              initial-size: 1
              max-size: 10
              max-idle-time: 30m
        

        【讨论】:

          猜你喜欢
          • 2012-04-30
          • 2021-09-25
          • 1970-01-01
          • 2021-06-24
          • 2021-08-20
          • 1970-01-01
          • 2011-08-13
          • 2015-12-19
          • 2018-02-18
          相关资源
          最近更新 更多