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

在配置 DBCP2 池时,根据文档,我注意到 - 有一个名为“的配置”,其描述为:timeBetweenEvictionRunsMillis

空闲对象逐行线程运行之间休眠的毫秒数。非正时,将不会运行空闲对象抖动线程。

其默认值为 。-1

这是否意味着 evictor 线程永远不会在默认配置中运行?然后如何强制执行配置参数 - 如果空闲连接计数大于 ,则池必须逐出空闲连接。maxIdlemaxIdle

在我看来,默认配置是这样的,即空闲连接永远不会被逐出,这似乎非常令人困惑。

还有另一种配置似乎在.softMiniEvictableIdleTimeMillistimeBetweenEvictionRunsMillis

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

目前,我正在配置如下池 - 因为我的目标是在池中长时间没有任何空闲连接(这是必需的,因为我们正在使用AWS RDS,并且似乎有一个奇怪的问题,我们经常遇到这个问题)

    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);

答案 1

是的,默认情况下,抖动线程不会运行。原因是 默认情况下,和 的值相同,这意味着不会立即关闭连接,也无需逐出空闲连接。因此,池只是通过不运行无用的线程来节省一些资源。maxIdlemaxTotal

但是,当您进行更改并使其低于不启动 evictor 线程时,并不意味着您的连接不会关闭。这意味着它们将在释放后立即关闭,没有延迟,直到它们的计数不下降到。maxIdlemaxTotalmaxIdle

然后来玩(小心,文档中有一个拼写错误,它是,而不是)。它们之间的区别在于,前者不尊重,而后者则尊重。考虑到仅在经过时才检查的事实,这有点棘手。minEvictableIdleTimeMillissoftMinEvictableIdleTimeMillis...MinEvictalbe......MiniEvictable...minIdlesoftMinEvictableIdleTimeMillisminEvictableIdleTimeMillis

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

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

最终,您将拥有连接和立即关闭,连接和关闭之后以及连接之后关闭并立即重新打开。给予或接受驱逐检查期。maxTotalmaxIdlemaxIdleminIdleminEvictableIdleTimeMillisminIdle0softMinEvictableIdleTimeMillis

使用您的配置,当池大于 20 时,您将立即关闭所有连接。这 20 个连接将在 10 到 20 分钟(即使空闲)之间有效,因为您有 10 分钟的连接,再加上 10 分钟的 .EvictableIdleTimeMillisTimeBetweenEvictionRunsMillis

我还想提一个潜在的问题,与 之间有很大的差距。如果你预计会经常超过,最好增加它。否则,您将面临不断的连接打开和关闭,这将对数据库(因为建立新的数据库连接是相对繁重的操作)和应用程序服务器网络基础结构(因为关闭的连接将挂起TIME_WAIT状态,从而耗尽网络端口池)造成额外的压力。maxIdlemaxTotalmaxIdle


答案 2

推荐