在数据库故障转移场景下使用HikariCP

问题描述 投票:0回答:1

我正在考虑将 hikariCP 与 AWS RDS 结合使用,并想澄清 hikariCP 有关数据库故障转移场景的一些规范。

  1. HikariCP 是否始终在从池中获取连接之后、应用程序使用连接之前验证连接?
    根据句子“这是在从池中向您提供连接之前执行的查询,以验证与数据库的连接是否仍然有效”。在 https://github.com/brettwooldridge/HikariCP 中,我猜总是执行连接验证。
    然而,此评论似乎表明并不总是执行连接验证。

  2. 如果始终执行上述连接验证,当执行的连接验证失败时,是立即向应用程序抛出异常还是从池中拾取另一个连接而不抛出异常?

  3. 如果从池中拾取另一个连接而不抛出异常,HikariCP 是否对此连接拾取有任何超时设置?
    我想

    connectionTimeout
    可能就是那个。

spring-boot database-connection hikaricp
1个回答
0
投票

将这些参数添加到jvm以进行DNS刷新 -Dnetworkaddress.cache.ttl=“60” -Dnetworkaddress.cache.negative.ttl=“10” -Dsun.net.inetaddr.ttl=60 -Dsun.net.inetaddr.negative.ttl=1

定期检查ForIpChange并逐出连接

private void checkForIpChange(HikariDataSource dataSource) {
        try {
            String ip = getIp(dataSource.getJdbcUrl());
            if (Objects.isNull(dataSourceIpMap.get(dataSource))) {
                dataSourceIpMap.put(dataSource, ip);
            } else if (!StringUtils.equals(ip, dataSourceIpMap.get(dataSource))) {
                log.info("writer ip changed, old is {} and new is {}", dataSourceIpMap.get(dataSource), ip);
                evictConnections(dataSource);
                dataSourceIpMap.put(dataSource, ip);
            }
        } catch (Exception e) {
            log.error("Caught exception in cname check", e);
        }
    }

    /**
     * soft eviction will add a new entry in the pool if the pool is not suspended, so suspend it
     * connection count is transient so take 10 zero samples to ensure full eviction
     * 60 sec wait time if all this does not work
     *
     * @param dataSource
     */
    private void evictConnections(HikariDataSource dataSource) {
        HikariPoolMXBean pool = dataSource.getHikariPoolMXBean();
        if (pool != null) {
            log.info("Active connection count is : {}, idle connection count is {} and total connection count is {}",
                    pool.getActiveConnections(), pool.getIdleConnections(), pool.getTotalConnections());
            log.info("suspending pool");
            pool.suspendPool();
            int zeroConnectionCount = 0;
            long currentTimeMillis = System.currentTimeMillis();
            for (long time = currentTimeMillis; time < currentTimeMillis + MAX_EVICT_WAIT_TIME_MILLS; time = time + 100) {
                pool.softEvictConnections();
                if (pool.getTotalConnections() == 0) {
                    zeroConnectionCount++;
                    if (zeroConnectionCount >= ZERO_CONNECTION_VALIDATION_COUNT) {
                        log.info("ZeroConnectionCount encountered {} times, so exiting loop", zeroConnectionCount);
                        break;
                    }
                }
            }
            log.info("resuming pool");
            pool.resumePool();
        }
    }

    private String getIp(String url) throws URISyntaxException, UnknownHostException {
        URI aURL = new URI(url);
        aURL = new URI(aURL.getSchemeSpecificPart());
        InetAddress address = InetAddress.getByName(aURL.getHost());
        return address.getHostAddress();
    }
© www.soinside.com 2019 - 2024. All rights reserved.