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);
是的,驱逐线程默认不会运行。原因是maxIdle
和maxTotal
的值默认是一样的,也就是说不会有连接立即关闭,也不需要驱逐空闲连接。因此,池只是通过不 运行 无用的线程来节省一些资源。
但是当你改变maxIdle
并使其低于maxTotal
而不启动驱逐线程时,这并不意味着你的连接不会被关闭。这意味着它们将在释放后立即关闭,没有延迟,直到它们的数量不下降到 maxIdle
.
然后 minEvictableIdleTimeMillis
和 softMinEvictableIdleTimeMillis
开始玩了(小心,文档中有错别字,是 ...MinEvictalbe...
,不是...MiniEvictable...
)。它们之间的区别在于前者不尊重 minIdle
而后者尊重。考虑到 softMinEvictableIdleTimeMillis
仅在 minEvictableIdleTimeMillis
过去时才检查这一事实,这有点棘手。
假设我们有 minEvictableIdleTimeMillis=10000
和 softMinEvictableIdleTimeMillis=-1
(默认情况下)。在这种情况下,空闲连接将在池中保留不超过 10 秒。即使连接数没有超过minIdle
,也会被关闭。如果它导致连接数低于 minIdle
,将立即创建一个新连接。
现在,假设我们有 minEvictableIdleTimeMillis=10000
和 softMinEvictableIdleTimeMillis=30000
。在这种情况下,在检查 minEvictableIdleTimeMillis
和检测到超出后的空闲连接将另外检查 softMinEvictableIdleTimeMillis
。如果空闲时间超过它,连接将被关闭。否则,它将在池中等待下一次针对 minEvictableIdleTimeMillis
.
的肯定检查
最终,maxTotal
和 maxIdle
之间的连接将立即关闭,maxIdle
和 minIdle
之间的连接将在 minEvictableIdleTimeMillis
之后关闭,并且minIdle
和 0
在 softMinEvictableIdleTimeMillis
之后关闭并立即重新打开。给予或接受驱逐检查期。
根据您的配置,当池大于 20 时,您将立即关闭所有连接。这 20 个连接将存在 10 到 20 分钟(即使空闲),因为您有 10 分钟的时间 EvictableIdleTimeMillis
加上10分钟的TimeBetweenEvictionRunsMillis
.
我还想提一下 maxIdle
和 maxTotal
之间存在巨大差距的潜在问题。如果您预计 maxIdle
会经常被超过,最好增加它。否则,您将面临持续的连接打开和关闭,这会给您的数据库(因为建立新的数据库连接是相对繁重的操作)和应用服务器网络基础设施(因为关闭的连接将挂起在 TIME_WAIT 状态)带来额外的压力耗尽您的网络端口池)。
在配置 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);
是的,驱逐线程默认不会运行。原因是maxIdle
和maxTotal
的值默认是一样的,也就是说不会有连接立即关闭,也不需要驱逐空闲连接。因此,池只是通过不 运行 无用的线程来节省一些资源。
但是当你改变maxIdle
并使其低于maxTotal
而不启动驱逐线程时,这并不意味着你的连接不会被关闭。这意味着它们将在释放后立即关闭,没有延迟,直到它们的数量不下降到 maxIdle
.
然后 minEvictableIdleTimeMillis
和 softMinEvictableIdleTimeMillis
开始玩了(小心,文档中有错别字,是 ...MinEvictalbe...
,不是...MiniEvictable...
)。它们之间的区别在于前者不尊重 minIdle
而后者尊重。考虑到 softMinEvictableIdleTimeMillis
仅在 minEvictableIdleTimeMillis
过去时才检查这一事实,这有点棘手。
假设我们有 minEvictableIdleTimeMillis=10000
和 softMinEvictableIdleTimeMillis=-1
(默认情况下)。在这种情况下,空闲连接将在池中保留不超过 10 秒。即使连接数没有超过minIdle
,也会被关闭。如果它导致连接数低于 minIdle
,将立即创建一个新连接。
现在,假设我们有 minEvictableIdleTimeMillis=10000
和 softMinEvictableIdleTimeMillis=30000
。在这种情况下,在检查 minEvictableIdleTimeMillis
和检测到超出后的空闲连接将另外检查 softMinEvictableIdleTimeMillis
。如果空闲时间超过它,连接将被关闭。否则,它将在池中等待下一次针对 minEvictableIdleTimeMillis
.
最终,maxTotal
和 maxIdle
之间的连接将立即关闭,maxIdle
和 minIdle
之间的连接将在 minEvictableIdleTimeMillis
之后关闭,并且minIdle
和 0
在 softMinEvictableIdleTimeMillis
之后关闭并立即重新打开。给予或接受驱逐检查期。
根据您的配置,当池大于 20 时,您将立即关闭所有连接。这 20 个连接将存在 10 到 20 分钟(即使空闲),因为您有 10 分钟的时间 EvictableIdleTimeMillis
加上10分钟的TimeBetweenEvictionRunsMillis
.
我还想提一下 maxIdle
和 maxTotal
之间存在巨大差距的潜在问题。如果您预计 maxIdle
会经常被超过,最好增加它。否则,您将面临持续的连接打开和关闭,这会给您的数据库(因为建立新的数据库连接是相对繁重的操作)和应用服务器网络基础设施(因为关闭的连接将挂起在 TIME_WAIT 状态)带来额外的压力耗尽您的网络端口池)。