16

プロジェクトをHikariCPに移動しました。これまでのところすべてうまくいっていますが、1 つの設定で問題が発生しています。

.setMaxLifetime(30*1000)HikariConfig オブジェクトでの設定です。この警告が表示されます

WARN com.zaxxer.hikari.HikariConfig - maxLifetime is less than 120000ms, using default 1800000ms.

私がしようとしているほど低く設定しないことを彼らが推奨していることを私は知っています。残念ながら、私が変更できない状況により、50 秒を超えて開いているすべての TCP 接続は、本番環境で終了します。

4

2 に答える 2

9

お使いのバージョンはわかりません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;
     }

このコードから、maxLifeTime は、デフォルトの 1800000 ミリ秒を使用して、少なくとも 120000 ミリ秒です。maxLifeTimeしたがって、を 30000ms(30*1000) に設定することはできません。HikariCPあなたのバージョンは少なくとも 2.2.4 より古いと思います。

しかし、最新HikariCPバージョン 2.7.4を見つけたとき。「この値を設定することを強くお勧めします。データベースまたはインフラストラクチャが課す接続時間制限よりも少なくとも 30 秒短くする必要があります。

同じクラス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;
    }

}

このコードから、maxLifeTime少なくともこのバージョンでは 30000ms に更新されています。

したがってHikariCP、maxLifeTime を 30000ms に設定したい場合は、バージョンを最新のバージョン 2.7.4 に更新してください。

ただし、HikariCP のバージョンを JDK 8 で 2.7.4 に更新する場合は、次の 2 つの点もお勧めします。

1.maxLifeTime値を 30000ms 以上に設定します。

2. mysql の( )maxLifeTimeよりも数分短い値を設定して、接続切断の例外を回避します。wait_timeoutshow variables like "%timeout%"

于 2017-12-07T11:45:05.033 に答える
3

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

そしてそれは動作します。ただし、次の点に注意してください。

 cpConfig.setMinimumIdle(0);

MSSQL などの DB に無限の MaxLifetime がある場合、これを厳密に 0 に設定する必要があります。そうしないと、多くの接続が無限に (無期限に) 閉じられません。

乾杯、
Artanis Zeratul

于 2018-12-06T02:28:33.857 に答える