我们使用最新版本的spring-data-r2dbc、r2dbc-pool和r2dbc-postgresql来使用连接池连接到PostgreSQL数据库。我们注意到一些较高的响应时间,远远高于数据库本身的查询响应时间(query_store.qs_view)。
我们向池中添加了一个metricsRecorder,为了调试目的,我们只在调用每个方法时打印。在每个SQL查询之前,我们得到的recordDestroyLatency调用似乎与池中的连接以及相同数量的recordAllocationSuccessAndLatency调用一样多。我们假设这意味着每个连接在每次查询之前都会被关闭和重新打开。然后,我们将其与数据库日志进行比较,并证明这是正确的:有相同数量的could not receive data from client: An existing connection was forcibly closed by the remote host和connection received:消息。
为什么会发生这种事?下面是我们用来创建连接工厂的代码。
@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只打印每个操作。对于查询本身,我们将扩展ReactiveCrudRepository接口。ConnectionPoolConfiguration在这里是最简单的形式,我们尝试添加诸如maxIdleTime或validationQuery之类的参数(就像我们为生产所做的那样),但是它似乎没有帮助。
发布于 2022-05-03 12:29:03
这是R2DBC池中已知的一个bug,这是问题。作为解决办法,应该显式地设置maxLifeTime,例如,我将其设置为以毫秒为单位的最大允许值(否则,如果设置为大于以毫秒为单位的最大允许值的值,R2DBC将抛出一个异常):
val cp = ConnectionPoolConfiguration.builder(cf)
.initialSize(poolInitialSize)
.maxSize(poolMaxSize)
.maxLifeTime(Duration.ofMillis(Long.MAX_VALUE))
.metricsRecorder(DatabaseMetricsRecorder())
.build()https://stackoverflow.com/questions/72056016
复制相似问题