HikariCP 保持活动查询泄露 Google Spanner 会话

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

我有一个使用 HikariCP 的 Spring Boot 应用程序。该应用程序连接到谷歌扳手数据库。我看到以下由 HikariCP 保持活动查询引起的会话泄漏异常

    at com.google.cloud.spanner.SessionPool$PooledSessionFuture.markCheckedOut(SessionPool.java:1338)
    at com.google.cloud.spanner.SessionPool$PooledSessionFuture.access$6200(SessionPool.java:1317)
    at com.google.cloud.spanner.SessionPool.checkoutSession(SessionPool.java:3270)
    at com.google.cloud.spanner.SessionPool.getSession(SessionPool.java:3251)
    at com.google.cloud.spanner.SessionPool.getMultiplexedSessionWithFallback(SessionPool.java:3186)
    at com.google.cloud.spanner.DatabaseClientImpl.getMultiplexedSession(DatabaseClientImpl.java:72)
    at com.google.cloud.spanner.DatabaseClientImpl.singleUseReadOnlyTransaction(DatabaseClientImpl.java:182)
    at com.google.cloud.spanner.connection.SingleUseTransaction.executeQueryAsync(SingleUseTransaction.java:237)
    at com.google.cloud.spanner.connection.ConnectionImpl.internalExecuteQuery(ConnectionImpl.java:1592)
    at com.google.cloud.spanner.connection.ConnectionImpl.internalExecute(ConnectionImpl.java:1022)
    at com.google.cloud.spanner.connection.ConnectionImpl.execute(ConnectionImpl.java:1001)
    at com.google.cloud.spanner.jdbc.AbstractJdbcStatement.lambda$execute$3(AbstractJdbcStatement.java:290)
    at com.google.cloud.spanner.jdbc.AbstractJdbcStatement.doWithStatementTimeout(AbstractJdbcStatement.java:230)
    at com.google.cloud.spanner.jdbc.AbstractJdbcStatement.execute(AbstractJdbcStatement.java:289)
    at com.google.cloud.spanner.jdbc.JdbcStatement.executeStatement(JdbcStatement.java:257)
    at com.google.cloud.spanner.jdbc.JdbcStatement.execute(JdbcStatement.java:248)
    at com.zaxxer.hikari.pool.PoolBase.isConnectionDead(PoolBase.java:165)
    at com.zaxxer.hikari.pool.HikariPool$KeepaliveTask.run(HikariPool.java:854)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.base/java.util.concurrent.FutureTask.runAndReset(Unknown Source)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)

如果我设置泄漏检测阈值,我的应用程序就会开始崩溃。顺便说一句,从业务逻辑内部触发的数据库查询也是泄漏会话。我正在使用 FluentJDBC 来查询数据库。 POM和代码片段如下

        var sourceDbHikariConfig = new HikariConfig();

        sourceDbHikariConfig.setDriverClassName(config.getDriverClassName());
        sourceDbHikariConfig.setJdbcUrl(config.getUrl());
        sourceDbHikariConfig.setUsername(config.getUsername());
        sourceDbHikariConfig.setPassword(config.getPassword());
        sourceDbHikariConfig.setConnectionTestQuery(config.getConnectionTestQuery());
        sourceDbHikariConfig.setKeepaliveTime(config.getKeepAliveTime());
        sourceDbHikariConfig.setMaximumPoolSize(config.getMaxPoolSize());
        sourceDbHikariConfig.setMinimumIdle(config.getMinIdleTime());
        sourceDbHikariConfig.setConnectionTimeout(config.getConnectionTimeout());

        return new HikariDataSource(sourceDbHikariConfig);

聚甲醛

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.myproject</groupId>
    <artifactId>my-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>my-project</name>

    <properties>
        <java.version>21</java.version>
    </properties>

    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20231013</version>
        </dependency>

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>5.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.9</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents.client5</groupId>
            <artifactId>httpclient5</artifactId>
            <version>5.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.codejargon</groupId>
            <artifactId>fluentjdbc</artifactId>
            <version>1.8.6</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>google-cloud-spanner-jdbc</artifactId>
            <version>2.13.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>google-cloud-bigtable</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.javafaker</groupId>
            <artifactId>javafaker</artifactId>
            <version>0.14</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>1.19.4</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.15.1</version>
        </dependency>


    </dependencies>



    <dependencyManagement>

        <dependencies>

            <dependency>
                <groupId>com.google.cloud</groupId>
                <artifactId>libraries-bom</artifactId>
                <version>26.39.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>

    </dependencyManagement>



    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
connection-pooling hikaricp google-cloud-spanner java-21
1个回答
0
投票

TLDR:至少更新至 Spanner JDBC 驱动程序版本 2.16.2。不过,建议始终使用最新版本的 Spanner JDBC 驱动程序。在撰写本文时,这是版本 2.20.1

不幸的是,这是将 HikariCP 与 Spanner JDBC 驱动程序一起使用时的一个已知问题。它已在 JDBC 驱动程序版本 2.16.2 中修复。泄漏的原因是 Hikari 执行查询,然后从未真正读取返回的数据,也从未关闭

ResultSet
。相反,用于执行保持活动查询的
Statement
被关闭,这应该足以释放该语句使用的所有资源。然而 JDBC 驱动程序未能清理尚未使用的
ResultSet

© www.soinside.com 2019 - 2024. All rights reserved.