Java HikariCP 和 maxLifetime
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28180562/
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
HikariCP and maxLifetime
提问by Gabriel
I moved my project to HikariCP. Everything is going fine so far, but with one setting I'm having trouble.
我将我的项目移至HikariCP。到目前为止一切都很好,但是在一个设置中我遇到了麻烦。
It's the .setMaxLifetime(30*1000)
setting in HikariConfig object. I get this warning
它是.setMaxLifetime(30*1000)
HikariConfig 对象中的设置。我收到这个警告
WARN com.zaxxer.hikari.HikariConfig - maxLifetime is less than 120000ms, using default 1800000ms.
I know that they recommend not setting is that low as I am trying to. But Unfortunately due to circumstances that I can not change, every TCP connection that is open longer than 50 secods will be terminated in our production environment.
我知道他们建议不要设置得像我想的那样低。但不幸的是,由于我无法改变的情况,每个打开超过 50 秒的 TCP 连接都将在我们的生产环境中终止。
回答by Java Basketball
i don't know your HikariCP
Version, but in the version 2.2.4 you will find the reason why it will throw the above warning.
HikariConfig.class
(in the com.zaxxer.hikari.HikariConfig
):
我不知道你的HikariCP
版本,但在 2.2.4 版本中你会发现它会抛出上述警告的原因。
HikariConfig.class
(在com.zaxxer.hikari.HikariConfig
):
private void More ...validateNumerics()
{
Logger logger = LoggerFactory.getLogger(getClass());
if (connectionTimeout == Integer.MAX_VALUE) {
logger.warn("No connection wait timeout is set, this might cause an infinite wait.");
}
if (minIdle < 0 || minIdle > maxPoolSize) {
minIdle = maxPoolSize;
}
if (maxLifetime < 0) {
logger.error("maxLifetime cannot be negative.");
throw new IllegalArgumentException("maxLifetime cannot be negative.");
}
else if (maxLifetime > 0 && maxLifetime < TimeUnit.SECONDS.toMillis(120)) {
logger.warn("maxLifetime is less than 120000ms, using default {}ms.", MAX_LIFETIME);
maxLifetime = MAX_LIFETIME;
}
if (idleTimeout != 0 && idleTimeout < TimeUnit.SECONDS.toMillis(30)) {
logger.warn("idleTimeout is less than 30000ms, using default {}ms.", IDLE_TIMEOUT);
idleTimeout = IDLE_TIMEOUT;
}
else if (idleTimeout > maxLifetime && maxLifetime > 0) {
logger.warn("idleTimeout is greater than maxLifetime, setting to maxLifetime.");
idleTimeout = maxLifetime;
}
from this code, the maxLifeTime is at least 120000ms, using default 1800000ms. so you can't set the maxLifeTime
to 30000ms(30*1000). I guess your HikariCP
version is at least older than 2.2.4.
从这段代码中,maxLifeTime 至少为 120000 毫秒,使用默认值 1800000 毫秒。所以你不能设置maxLifeTime
为 30000ms(30*1000)。我猜你的HikariCP
版本至少比 2.2.4 旧。
But when you find the latest HikariCP
version 2.7.4. it said "We strongly recommend setting this value, and it should be at least 30 seconds less than any database or infrastructure imposed connection time limit."
但是当你找到最新HikariCP
版本 2.7.4 时。它说“我们强烈建议设置这个值,它应该至少比任何数据库或基础设施强加的连接时间限制少 30 秒。”
the same class HikariConfig.class
:
同一个班级HikariConfig.class
:
private void validateNumerics() {
if(this.maxLifetime != 0L && this.maxLifetime < TimeUnit.SECONDS.toMillis(30L)) {
LOGGER.warn("{} - maxLifetime is less than 30000ms, setting to default {}ms.", this.poolName, Long.valueOf(MAX_LIFETIME));
this.maxLifetime = MAX_LIFETIME;
}
if(this.idleTimeout + TimeUnit.SECONDS.toMillis(1L) > this.maxLifetime && this.maxLifetime > 0L) {
LOGGER.warn("{} - idleTimeout is close to or more than maxLifetime, disabling it.", this.poolName);
this.idleTimeout = 0L;
}
if(this.idleTimeout != 0L && this.idleTimeout < TimeUnit.SECONDS.toMillis(10L)) {
LOGGER.warn("{} - idleTimeout is less than 10000ms, setting to default {}ms.", this.poolName, Long.valueOf(IDLE_TIMEOUT));
this.idleTimeout = IDLE_TIMEOUT;
}
if(this.leakDetectionThreshold > 0L && !unitTest && (this.leakDetectionThreshold < TimeUnit.SECONDS.toMillis(2L) || this.leakDetectionThreshold > this.maxLifetime && this.maxLifetime > 0L)) {
LOGGER.warn("{} - leakDetectionThreshold is less than 2000ms or more than maxLifetime, disabling it.", this.poolName);
this.leakDetectionThreshold = 0L;
}
if(this.connectionTimeout < 250L) {
LOGGER.warn("{} - connectionTimeout is less than 250ms, setting to {}ms.", this.poolName, Long.valueOf(CONNECTION_TIMEOUT));
this.connectionTimeout = CONNECTION_TIMEOUT;
}
if(this.validationTimeout < 250L) {
LOGGER.warn("{} - validationTimeout is less than 250ms, setting to {}ms.", this.poolName, Long.valueOf(VALIDATION_TIMEOUT));
this.validationTimeout = VALIDATION_TIMEOUT;
}
if(this.maxPoolSize < 1) {
this.maxPoolSize = this.minIdle <= 0?10:this.minIdle;
}
if(this.minIdle < 0 || this.minIdle > this.maxPoolSize) {
this.minIdle = this.maxPoolSize;
}
}
from this code, the maxLifeTime
has been updated to 30000ms at least in this version.
从这段代码中,maxLifeTime
至少在这个版本中已经更新到 30000 毫秒。
So now please update your HikariCP
version to the latest version 2.7.4 if you want to set maxLifeTime to 30000ms.
因此,HikariCP
如果您想将 maxLifeTime 设置为 30000 毫秒,现在请将您的版本更新到最新版本 2.7.4。
But if you update your HikariCP version to 2.7.4 with JDK 8, i also recommend you two points:
但是,如果您使用 JDK 8 将 HikariCP 版本更新为 2.7.4,我还建议您注意两点:
1. to set maxLifeTime
value to be at least 30000ms.
1. 设置maxLifeTime
值至少为 30000ms。
2. to set maxLifeTime
value few minute less than mysql's wait_timeout
(show variables like "%timeout%"
) to avoid broken connection exception.
2. 将maxLifeTime
值设置为比mysql的wait_timeout
( show variables like "%timeout%"
)少几分钟以避免断开连接异常。
回答by Artanis Zeratul
Using Hikari version 2.7.9 and I made the following settings:
使用 Hikari 2.7.9 版,我进行了以下设置:
HikariConfig cpConfig = new HikariConfig();
cpConfig.setJdbcUrl(jdbcUrl);
cpConfig.setUsername(username);
cpConfig.setPassword(password);
cpConfig.setMaximumPoolSize(15);
cpConfig.setConnectionTestQuery("SELECT 1");
// performance senstive settings
cpConfig.setMinimumIdle(0);
cpConfig.setConnectionTimeout(30000);
cpConfig.setIdleTimeout(35000);
cpConfig.setMaxLifetime(45000);
cpConfig.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
HikariDataSource cpDatasource = new HikariDataSource(cpConfig);
localContainerEntityManagerFactoryBean.setDataSource(cpDatasource);
localContainerEntityManagerFactoryBean.setJpaProperties(jpaProperties);
localContainerEntityManagerFactoryBean.afterPropertiesSet();
and it works. But please be careful with:
它有效。但请注意:
cpConfig.setMinimumIdle(0);
If your DB e.g. like MSSQL has infinite MaxLifetime this has to be set strictly to 0 or else you will have many connections not closed infinitely (indefinitely)
Cheers,
Artanis Zeratul
如果您的数据库(例如 MSSQL)具有无限的 MaxLifetime,则必须将其严格设置为 0,否则您将有许多连接不会无限(无限期)关闭
干杯,
Artanis Zeratul