java DBCP2 - 何时从池中删除空闲连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38685092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
DBCP2 - When are Idle connections removed from the Pool
提问by Wand Maker
While configuring DBCP2 pool, and based on documentationI noticed that - there is a configuration called timeBetweenEvictionRunsMillis
which is described as:
在配置 DBCP2 池时,根据文档,我注意到 - 有一个名为的配置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.
在空闲对象驱逐线程的运行之间休眠的毫秒数。当非正数时,不会运行空闲对象驱逐线程。
Its default value is -1
.
其默认值为-1
。
Does this mean that evictor thread will never run in default configuration? Then how is the configuration parameter maxIdle
enforced - the pool has to evict idle connections if their count is greater than maxIdle
.
这是否意味着 evictor 线程永远不会在默认配置中运行?那么如何maxIdle
强制执行配置参数- 如果空闲连接的数量大于 ,则池必须驱逐空闲连接maxIdle
。
It seems very confusing to me that default configuration is such that idle connections are never evicted.
我似乎很困惑,默认配置是这样的,空闲连接永远不会被驱逐。
There is also another configuration softMiniEvictableIdleTimeMillis
which seems to play some role on top of timeBetweenEvictionRunsMillis
.
还有另一种配置softMiniEvictableIdleTimeMillis
似乎在timeBetweenEvictionRunsMillis
.
Any clarifications in this regard will be of immense help.
在这方面的任何澄清都将大有帮助。
For time being, I am configuring the pool like below - as my goal is to not have any idle connections in my pool for too long (this was needed as we are using AWS RDS and there seem to be a weird issuewith it which we are running into frequently)
目前,我正在像下面这样配置池 - 因为我的目标是在我的池中没有任何空闲连接太长时间(这是必需的,因为我们使用 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);
回答by Andrew Lygin
Yes, the evictor thread will not run by default. The reason is that the values of maxIdle
and maxTotal
are the same by default, which means there will be no connections to close immediately, and no need in evicting idle connections. So, the pool just saves some resources by not running a useless thread.
是的,默认情况下驱逐线程不会运行。其原因是,值maxIdle
和maxTotal
默认情况下是相同的,这意味着将有无可立即关闭,并驱逐空闲连接没有必要。因此,池只是通过不运行无用线程来节省一些资源。
But when you change maxIdle
and make it lower than maxTotal
without starting the evictor thread, it doesn't mean that your connections will not be closed. It means they will be closed immediately after releasing, with no delay, until their count not drop down to maxIdle
.
但是当你改变maxIdle
并使它低于maxTotal
没有启动 evictor 线程时,这并不意味着你的连接不会被关闭。这意味着它们将在释放后立即关闭,没有延迟,直到它们的计数不下降到maxIdle
.
And then minEvictableIdleTimeMillis
and softMinEvictableIdleTimeMillis
come to play (be careful, there's a typo in the documentation, it's ...MinEvictalbe...
, not ...MiniEvictable...
). The difference between them is that the former doesn't respect minIdle
while the latter does. It's a bit tricky given the fact that softMinEvictableIdleTimeMillis
is only checked when minEvictableIdleTimeMillis
has elapsed.
然后minEvictableIdleTimeMillis
与softMinEvictableIdleTimeMillis
前来游玩(要小心,有文档中一个错字,它...MinEvictalbe...
不是...MiniEvictable...
)。它们的区别在于前者不尊重minIdle
,后者尊重。鉴于softMinEvictableIdleTimeMillis
仅在minEvictableIdleTimeMillis
经过时才检查这一事实,这有点棘手。
Let's assume we have minEvictableIdleTimeMillis=10000
and softMinEvictableIdleTimeMillis=-1
(by default). In such case an idle connection will remain in the pool for no longer than 10 seconds. Even if the number of connections does not exceed minIdle
, it will be closed. If it lead to dropping of the connections count lower than minIdle
, a new connection will be created immediately.
假设我们有minEvictableIdleTimeMillis=10000
和softMinEvictableIdleTimeMillis=-1
(默认情况下)。在这种情况下,空闲连接将在池中保留不超过 10 秒。即使连接数不超过minIdle
,也会被关闭。如果它导致连接计数低于minIdle
,则将立即创建一个新连接。
Now, let's assume that we have minEvictableIdleTimeMillis=10000
and softMinEvictableIdleTimeMillis=30000
. In such case an idle connection after checking against minEvictableIdleTimeMillis
and detection of exceeding will be additionally checked against softMinEvictableIdleTimeMillis
. If the idle time exceeds it, the connection will be closed. Otherwise, it will sit in the pool till the next positive check against minEvictableIdleTimeMillis
.
现在,让我们假设我们有minEvictableIdleTimeMillis=10000
和softMinEvictableIdleTimeMillis=30000
。在这种情况下,检查minEvictableIdleTimeMillis
和检测超出后的空闲连接将另外检查softMinEvictableIdleTimeMillis
。如果空闲时间超过它,连接将被关闭。否则,它将留在池中,直到下一次针对 的正面检查minEvictableIdleTimeMillis
。
Eventually, you'll have connections between maxTotal
and maxIdle
closed immediately, connections between maxIdle
and minIdle
closed after minEvictableIdleTimeMillis
and connections between minIdle
and 0
closed after softMinEvictableIdleTimeMillis
and reopened immediately. Give or take the eviction check period.
最终,您将在maxTotal
和之间maxIdle
立即关闭连接,在maxIdle
和minIdle
之后关闭minEvictableIdleTimeMillis
连接以及在minIdle
和0
之后关闭softMinEvictableIdleTimeMillis
并立即重新打开连接。给予或接受驱逐检查期。
With your configuration, you will have all the connections closed immediately while the pool is larger than 20. And those 20 connections will live from 10 to 20 minutes (even if idle) because you have 10 minutes of both EvictableIdleTimeMillis
plus 10 minutes of TimeBetweenEvictionRunsMillis
.
使用您的配置,当池大于 20 时,您将立即关闭所有连接。这 20 个连接将存活 10 到 20 分钟(即使空闲),因为您有 10 分钟的时间EvictableIdleTimeMillis
加上 10 分钟的TimeBetweenEvictionRunsMillis
.
I'd like to also mention a potential problem with large gap between maxIdle
and maxTotal
. If you expect that maxIdle
will be exceeded very often, it's better to increase it. Otherwise, you'll face constant connection openings and closings which will create additional pressure on your database (because establishing a new db connection is relatively heavy operation) and the app server network infrastructure (because closed connections will hang in TIME_WAIT status depleting your network ports pool).
我还想提一下maxIdle
和之间存在巨大差距的潜在问题maxTotal
。如果您预计maxIdle
会经常超过该值,则最好增加它。否则,您将面临不断的连接打开和关闭,这将对您的数据库(因为建立新的 db 连接是相对繁重的操作)和应用服务器网络基础设施(因为关闭的连接将挂在 TIME_WAIT 状态,耗尽您的网络端口)造成额外压力水池)。