Java HikariCP:等待连接后超时

Java HikariCP:等待连接后超时,java,spring,postgresql,connection-pooling,hikaricp,Java,Spring,Postgresql,Connection Pooling,Hikaricp,我正在开发一个SpringMVC应用程序,我们正在使用HikariCP。我们使用PostgreSQL作为数据库,PostgreSQL中有150个连接,Hikari有15个池大小。有时,我们会突然发现发生超时的错误。错误会在10-20秒内消失,但会降低整个服务器的速度。很多时候它甚至都不忙。我尝试了一些其他线程并添加了泄漏检测,但没有任何帮助。你知道我做错了什么,或者如何解决这个问题吗 错误日志: java.sql.SQLTimeoutException: Timeout after 30000m

我正在开发一个SpringMVC应用程序,我们正在使用HikariCP。我们使用PostgreSQL作为数据库,PostgreSQL中有150个连接,Hikari有15个池大小。有时,我们会突然发现发生超时的错误。错误会在10-20秒内消失,但会降低整个服务器的速度。很多时候它甚至都不忙。我尝试了一些其他线程并添加了泄漏检测,但没有任何帮助。你知道我做错了什么,或者如何解决这个问题吗

错误日志:

java.sql.SQLTimeoutException: Timeout after 30000ms of waiting for a connection.
        at com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:233)
        at com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:183)
        at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:110)
root-context.xml:

<beans:bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"  destroy-method="close">
    <beans:property name="dataSourceClassName" value="org.postgresql.ds.PGSimpleDataSource"/>
    <beans:property name="minimumIdle" value="2"/>
   <beans:property name="maximumPoolSize" value="17" />
    <beans:property name="maxLifetime" value="300000" />
    <beans:property name="idleTimeout" value="25000" />
    <beans:property name="leakDetectionThreshold" value="3000"/>
    <beans:property name="dataSourceProperties">
        <beans:props>
            <beans:prop key="url">jdbc:postgresql://localhost:5432/DB_NAME</beans:prop>
            <beans:prop key="user">USERnamE</beans:prop>
            <beans:prop key="password">PASSWORD</beans:prop>
        </beans:props>
    </beans:property>
</beans:bean>

<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
            class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <beans:property name="dataSource" ref="dataSource"/>
    <beans:property name="packagesToScan" value="com.ourapp.spring.model"/>
    <beans:property name="hibernateProperties">
        <beans:props>
            <beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
            <beans:prop key="hibernate.show_sql">false</beans:prop>
            <beans:prop key="hibernate.jdbc.batch_size">50</beans:prop>
            <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
            <beans:prop key="cache.use_second_level_cache">true</beans:prop>
            <beans:prop key="cache.use_query_cache">true</beans:prop>
            <beans:prop key="hibernate.order_updates">true</beans:prop>
            <beans:prop key="show_sql">false</beans:prop>
        </beans:props>
    </beans:property>
</beans:bean>

由于应用程序业务逻辑的原因,连接不足。就像你说的:

问题是,我大部分都是短期运行的事务,很少有长期运行的事务

不是为短时间运行的事务增加池大小,而是为长时间运行的事务声明一个单独的新
DataSource
bean。这个新的
数据源
应该由新的HikariCP池支持。它的最小大小甚至可以为0,因为如果您正在运行长时间运行的事务(例如,月报),则建立新数据库连接的成本应该是微不足道的


分离OLTP和OLAP处理是正确的方法,例如,请参阅。例如,您可以每天刷新一个单独的OLAP数据库来处理报告,而主OLTP数据库不受耗时的报告工作负载的影响。

由于您的应用程序业务逻辑,连接已用尽。就像你说的:

问题是,我大部分都是短期运行的事务,很少有长期运行的事务

不是为短时间运行的事务增加池大小,而是为长时间运行的事务声明一个单独的新
DataSource
bean。这个新的
数据源
应该由新的HikariCP池支持。它的最小大小甚至可以为0,因为如果您正在运行长时间运行的事务(例如,月报),则建立新数据库连接的成本应该是微不足道的


分离OLTP和OLAP处理是正确的方法,例如,请参阅。例如,您可以每天刷新一个单独的OLAP数据库来处理报告,而主OLTP数据库不受耗时的报告工作负载的影响。

更改Postgres驱动程序并更改hikaricp的设置

spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=30000   
spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal
.HikariCPConnectionProvider

更改Postgres驱动程序并更改hikaricp的设置

spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=30000   
spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal
.HikariCPConnectionProvider

那么游泳池的大小对你来说够大吗?如果已检查连接是否泄漏,则池设置的事务太多/太长。增加池大小会有所帮助,但我相信您也读过关于连接池大小的HikariCP文章。@Kayaman:问题是我的事务大多是短期运行的,很少是长期运行的。我上次尝试将池大小从10-15增加,但没有解决问题,有时应用程序处于空闲状态,当我尝试访问它时,会出现此错误。如果应用程序处于空闲状态,则您确实存在连接泄漏。然而,这不应该“在20秒内消失”。配置HikariCP以打印池统计信息,并研究这些统计信息以查看池内发生的情况。@Kayaman:知道如何用XML实现这一点吗,大部分代码都是用Java编写的。谢谢是的,这是一个奇怪的部分,它只是减慢了10-15秒,然后一切都启动并运行。检查Hikari文档中的相关参数。编辑:啊,你需要接受Dropwizard/Codahale的度量。对你来说可能吗?那么游泳池的大小对你来说足够大吗?如果已检查连接是否泄漏,则池设置的事务太多/太长。增加池大小会有所帮助,但我相信您也读过关于连接池大小的HikariCP文章。@Kayaman:问题是我的事务大多是短期运行的,很少是长期运行的。我上次尝试将池大小从10-15增加,但没有解决问题,有时应用程序处于空闲状态,当我尝试访问它时,会出现此错误。如果应用程序处于空闲状态,则您确实存在连接泄漏。然而,这不应该“在20秒内消失”。配置HikariCP以打印池统计信息,并研究这些统计信息以查看池内发生的情况。@Kayaman:知道如何用XML实现这一点吗,大部分代码都是用Java编写的。谢谢是的,这是一个奇怪的部分,它只是减慢了10-15秒,然后一切都启动并运行。检查Hikari文档中的相关参数。编辑:啊,你需要接受Dropwizard/Codahale的度量。你有可能吗?谢谢你的回答。我通过创建一个新的数据源来尝试你的建议。我在这件事上犯了一个错误。你能看看这个吗:谢谢你的回答。我通过创建一个新的数据源来尝试你的建议。我在这件事上犯了一个错误。你能看看这个吗: