jdbcTemplate 连接泄漏到 Spring 引导中的 postgresql 数据库

jdbcTemplate connection leak to postgresql db in Spring Boot

我的服务好像有数据库连接泄漏。昨天重新部署后,我提到有 27 个打开的 postgres 数据库连接。今天早上他们 60 岁。

对我的数据库执行此查询我看到某些连接的最后一次使用时间是昨天。

SELECT * FROM pg_stat_activity
ORDER BY state_change DESC

我的 jdbcTemplate 似乎应该关闭它们,但它没有这样做。

这是我的配置

@Configuration
public class DatabaseConfiguration {
    // reading data from application properties
    // ........

    private DataSource configureDataSource(String url, String user, String password, String driverClassName){
        DataSource ds = DataSourceBuilder.create()
                .url(url)
                .username(user)
                .password(password)
                .driverClassName(driverClassName)
                .build();

        org.apache.tomcat.jdbc.pool.DataSource configuredDataSource = (org.apache.tomcat.jdbc.pool.DataSource) ds;
        configuredDataSource.setTestWhileIdle(connectionTestWhileIdle);
        configuredDataSource.setValidationQuery( connectionValidationQuery);
        configuredDataSource.setTimeBetweenEvictionRunsMillis( 
              toIntExact(connectionTimeBetweenEvictionRunsMillis));

        return configuredDataSource;
    }

    @Bean(name = "qaDataSource")
    public JdbcTemplate getQaJdbcTemplate()  {
        DataSource ds = configureDataSource(qaURL, qaUsername, qaPassword ,qaDriverClassName);
        return new JdbcTemplate(ds);
    }

知道我的配置有什么问题吗?或者这可能是错误的数据库配置。

经过几个小时的调查,这个连接泄漏似乎是由我们集群内部的 http 请求超时和其他网络问题引起的。

如果从我的服务向 postgres 数据库发送请求并且发生了一些网络问题,连接将保持活动状态。一段时间后,达到最大活动连接数,服务无法再连接到数据库。

作为解决方法,虽然未找到网络问题的根源,但为了避免工作一段时间后服务中断,我在 configureDataSource 方法

中配置了 RemoveAbandoned 验证
configuredDataSource.getPoolProperties().setRemoveAbandonedTimeout(300);
configuredDataSource.getPoolProperties().setRemoveAbandoned(true);

这将检查处于活动状态的连接是否超过 5 分钟,如果超过 5 分钟,连接将被视为已放弃并关闭。不要忘记确保 RemoveAbandonedTimeout 应该超过服务中任何 sql 查询的最长执行时间。