R2DBC池在每个查询之前关闭所有连接

发布于 2025-01-24 20:53:51 字数 1537 浏览 4 评论 0原文

我们正在使用Spring-Data-R2DBCR2DBC-POOLR2DBC-POSTGRESQL使用连接池。我们注意到了一些很高的响应时间,比从数据库本身获取的查询响应时间高得多(query_store.qs_view),

我们在池中添加了MetricsRecorder,用于调试目的,我们只在调用每种方法时才打印。看来,在每个SQL查询之前,我们获得了与池中有连接相同的RecordDestroylatency调用,并且recodallocationsuccessandlatency Invocations数量相同。我们假设这意味着每个连接在每个查询之前都会关闭并重新打开。然后,我们将其与数据库日志进行了比较,并证明这是真的:数量相同,无法从客户端接收数据:现有连接被远程主机,然后是连接。收到:消息。

为什么会发生这种情况?以下是我们用于创建连接工厂的代码。

@Configuration
open class DatabaseConfiguration : AbstractR2dbcConfiguration() {

//some variable initialisations

    @Bean
    override fun connectionFactory(): ConnectionFactory {
        val cf = PostgresqlConnectionFactory(
            PostgresqlConnectionConfiguration.builder()
                .host(hostname)
                .database(dbName)
                .schema(dbSchema)
                .username(dbUsername)
                .password(dbPassword)
                .build()
        )
        val cp = ConnectionPoolConfiguration.builder(cf)
            .initialSize(poolInitialSize)
            .maxSize(poolMaxSize)
            .metricsRecorder(DatabaseMetricsRecorder())
            .build()
        return ConnectionPool(cp)
    }
}

如前所述,databasemetricsRecorder只需打印每个操作即可。对于查询本身,我们正在扩展reactivevecrudrepository接口。 connection -continepoolConfiguration在此处以最简单的形式似乎有帮助。

We're using the latest versions of spring-data-r2dbc, r2dbc-pool and r2dbc-postgresql for connecting to a PostgreSQL database using a connection pool. We noticed some high response times, much higher than the query response times taken from the database itself (query_store.qs_view)

We added a metricsRecorder to the pool and, for debugging purposes, we're only printing when each method is invoked. It seems that before each SQL query, we get as many recordDestroyLatency invocations as there are connections in the pool and the same number of recordAllocationSuccessAndLatency invocations. We assumed that this means that each connection gets closed and reopened before each query. We then compared with the database logs and it proves this is true: there is the same number of could not receive data from client: An existing connection was forcibly closed by the remote host followed by connection received: messages.

Why would this happen? Below is the code we're using for creating the connection factory.

@Configuration
open class DatabaseConfiguration : AbstractR2dbcConfiguration() {

//some variable initialisations

    @Bean
    override fun connectionFactory(): ConnectionFactory {
        val cf = PostgresqlConnectionFactory(
            PostgresqlConnectionConfiguration.builder()
                .host(hostname)
                .database(dbName)
                .schema(dbSchema)
                .username(dbUsername)
                .password(dbPassword)
                .build()
        )
        val cp = ConnectionPoolConfiguration.builder(cf)
            .initialSize(poolInitialSize)
            .maxSize(poolMaxSize)
            .metricsRecorder(DatabaseMetricsRecorder())
            .build()
        return ConnectionPool(cp)
    }
}

As mentioned, the DatabaseMetricsRecorder just prints each operation. For the query itself, we're extending the ReactiveCrudRepository interface. The ConnectionPoolConfiguration is in its simplest form here, we tried adding parameters like maxIdleTime or validationQuery (as we'll have for production) but it doesn't seem to help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁吢 2025-01-31 20:53:51

这是R2DBC池中的一个已知错误,这是 evary 。作为解决方法,应明确设置maxlifetime,例如,我将其设置为毫秒中的最大允许值(否则,如果设置为一个值大于毫秒中的最大允许值,则R2DBC将投掷一个例外):

    val cp = ConnectionPoolConfiguration.builder(cf)
        .initialSize(poolInitialSize)
        .maxSize(poolMaxSize)
        .maxLifeTime(Duration.ofMillis(Long.MAX_VALUE))
        .metricsRecorder(DatabaseMetricsRecorder())
        .build()

It's a known bug in R2DBC pool, here's the issue. As a workaround, maxLifeTime should be explicitly set, for example I set it to the maximum allowed value in milliseconds (otherwise, if set to a value greater than the maximum allowed value in milliseconds, R2DBC will throw an Exception):

    val cp = ConnectionPoolConfiguration.builder(cf)
        .initialSize(poolInitialSize)
        .maxSize(poolMaxSize)
        .maxLifeTime(Duration.ofMillis(Long.MAX_VALUE))
        .metricsRecorder(DatabaseMetricsRecorder())
        .build()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文