DBCP2 - 何时从池中删除空闲连接

DBCP2 - When are Idle connections removed from the Pool

在配置 DBCP2 池时,基于 documentation 我注意到 - 有一个名为 timeBetweenEvictionRunsMillis 的配置,描述为:

The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle object evictor thread will be run.

其默认值为-1

这是否意味着在默认配置中逐出线程永远不会 运行?那么配置参数 maxIdle 是如何强制执行的——如果空闲连接的数量大于 maxIdle.

,池必须驱逐空闲连接

我似乎很困惑,默认配置是永远不会驱逐空闲连接。

还有一个配置 softMiniEvictableIdleTimeMillis 似乎在 timeBetweenEvictionRunsMillis 之上发挥了一些作用。

在这方面的任何澄清都会有很大的帮助。

目前,我正在如下配置池 - 因为我的目标是在我的池中没有任何空闲连接太久(这是需要的,因为我们正在使用 AWS RDS 并且似乎 a weird issue 我们 运行 经常使用它)

    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl(properties.getProperty("app.mysql.url"));
    dataSource.setUsername(properties.getProperty("app.mysql.username"));
    dataSource.setPassword(properties.getProperty("app.mysql.password"));
    dataSource.setMaxIdle(20);
    dataSource.setMaxWaitMillis(20000); //wait 10 seconds to get new connection
    dataSource.setMaxTotal(200);
    dataSource.setMinIdle(0);
    dataSource.setInitialSize(10);
    dataSource.setTestOnBorrow(true);
    dataSource.setValidationQuery("select 1");
    dataSource.setValidationQueryTimeout(10); //The value is in seconds

    dataSource.setTimeBetweenEvictionRunsMillis(600000); // 10 minutes wait to run evictor process
    dataSource.setSoftMinEvictableIdleTimeMillis(600000); // 10 minutes wait to run evictor process
    dataSource.setMinEvictableIdleTimeMillis(60000); // 60 seconds to wait before idle connection is evicted
    dataSource.setMaxConnLifetimeMillis(600000); // 10 minutes is max life time
    dataSource.setNumTestsPerEvictionRun(10);

是的,驱逐线程默认不会运行。原因是maxIdlemaxTotal的值默认是一样的,也就是说不会有连接立即关闭,也不需要驱逐空闲连接。因此,池只是通过不 运行 无用的线程来节省一些资源。

但是当你改变maxIdle并使其低于maxTotal而不启动驱逐线程时,这并不意味着你的连接不会被关闭。这意味着它们将在释放后立即关闭,没有延迟,直到它们的数量不下降到 maxIdle.

然后 minEvictableIdleTimeMillissoftMinEvictableIdleTimeMillis 开始玩了(小心,文档中有错别字,是 ...MinEvictalbe...,不是...MiniEvictable...)。它们之间的区别在于前者不尊重 minIdle 而后者尊重。考虑到 softMinEvictableIdleTimeMillis 仅在 minEvictableIdleTimeMillis 过去时才检查这一事实,这有点棘手。

假设我们有 minEvictableIdleTimeMillis=10000softMinEvictableIdleTimeMillis=-1(默认情况下)。在这种情况下,空闲连接将在池中保留不超过 10 秒。即使连接数没有超过minIdle,也会被关闭。如果它导致连接数低于 minIdle,将立即创建一个新连接。

现在,假设我们有 minEvictableIdleTimeMillis=10000softMinEvictableIdleTimeMillis=30000。在这种情况下,在检查 minEvictableIdleTimeMillis 和检测到超出后的空闲连接将另外检查 softMinEvictableIdleTimeMillis。如果空闲时间超过它,连接将被关闭。否则,它将在池中等待下一次针对 minEvictableIdleTimeMillis.

的肯定检查

最终,maxTotalmaxIdle 之间的连接将立即关闭,maxIdleminIdle 之间的连接将在 minEvictableIdleTimeMillis 之后关闭,并且minIdle0softMinEvictableIdleTimeMillis 之后关闭并立即重新打开。给予或接受驱逐检查期。

根据您的配置,当池大于 20 时,您将立即关闭所有连接。这 20 个连接将存在 10 到 20 分钟(即使空闲),因为您有 10 分钟的时间 EvictableIdleTimeMillis加上10分钟的TimeBetweenEvictionRunsMillis.

我还想提一下 maxIdlemaxTotal 之间存在巨大差距的潜在问题。如果您预计 maxIdle 会经常被超过,最好增加它。否则,您将面临持续的连接打开和关闭,这会给您的数据库(因为建立新的数据库连接是相对繁重的操作)和应用服务器网络基础设施(因为关闭的连接将挂起在 TIME_WAIT 状态)带来额外的压力耗尽您的网络端口池)。