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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:40:23  来源:igfitidea点击:

DBCP2 - When are Idle connections removed from the Pool

javaconnection-poolingapache-commons-dbcp

提问by Wand Maker

While configuring DBCP2 pool, and based on documentationI noticed that - there is a configuration called timeBetweenEvictionRunsMilliswhich 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 maxIdleenforced - 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 softMiniEvictableIdleTimeMilliswhich 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 maxIdleand maxTotalare 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.

是的,默认情况下驱逐线程不会运行。其原因是,值maxIdlemaxTotal默认情况下是相同的,这意味着将有无可立即关闭,并驱逐空闲连接没有必要。因此,池只是通过不运行无用线程来节省一些资源。

But when you change maxIdleand make it lower than maxTotalwithout 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 minEvictableIdleTimeMillisand softMinEvictableIdleTimeMilliscome 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 minIdlewhile the latter does. It's a bit tricky given the fact that softMinEvictableIdleTimeMillisis only checked when minEvictableIdleTimeMillishas elapsed.

然后minEvictableIdleTimeMillissoftMinEvictableIdleTimeMillis前来游玩(要小心,有文档中一个错字,它...MinEvictalbe...不是...MiniEvictable...)。它们的区别在于前者不尊重minIdle,后者尊重。鉴于softMinEvictableIdleTimeMillis仅在minEvictableIdleTimeMillis经过时才检查这一事实,这有点棘手。

Let's assume we have minEvictableIdleTimeMillis=10000and 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=10000softMinEvictableIdleTimeMillis=-1(默认情况下)。在这种情况下,空闲连接将在池中保留不超过 10 秒。即使连接数不超过minIdle,也会被关闭。如果它导致连接计数低于minIdle,则将立即创建一个新连接。

Now, let's assume that we have minEvictableIdleTimeMillis=10000and softMinEvictableIdleTimeMillis=30000. In such case an idle connection after checking against minEvictableIdleTimeMillisand 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=10000softMinEvictableIdleTimeMillis=30000。在这种情况下,检查minEvictableIdleTimeMillis和检测超出后的空闲连接将另外检查softMinEvictableIdleTimeMillis。如果空闲时间超过它,连接将被关闭。否则,它将留在池中,直到下一次针对 的正面检查minEvictableIdleTimeMillis

Eventually, you'll have connections between maxTotaland maxIdleclosed immediately, connections between maxIdleand minIdleclosed after minEvictableIdleTimeMillisand connections between minIdleand 0closed after softMinEvictableIdleTimeMillisand reopened immediately. Give or take the eviction check period.

最终,您将在maxTotal和之间maxIdle立即关闭连接,在maxIdleminIdle之后关闭minEvictableIdleTimeMillis连接以及在minIdle0之后关闭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 EvictableIdleTimeMillisplus 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 maxIdleand maxTotal. If you expect that maxIdlewill 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 状态,耗尽您的网络端口)造成额外压力水池)。