1

看来我的服务存在数据库连接泄漏。昨天重新部署后,我提到有 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);
    }

任何想法我的配置有什么问题?或者也许这是错误的数据库配置。

4

1 回答 1

1

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

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

作为一种解决方法,虽然没有找到网络问题的根源,但为了避免在工作一段时间后服务关闭,我在我的方法中配置RemoveAbandoned了验证configureDataSource

configuredDataSource.getPoolProperties().setRemoveAbandonedTimeout(300);
configuredDataSource.getPoolProperties().setRemoveAbandoned(true);

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

于 2018-05-22T07:13:02.157 回答