最大连接被奇怪地炸毁,而大量空闲连接

Max connection is weirdly blown up while lots of idle connections

我检查过 max available connection 应该是 97,因为我的 max_connection 是 100superuser_reserved_connections 默认是 3。

我正在使用 hibernate-envers 5.2.3.Final and Spring Boot 1.5.2.RELEASE 来管理数据库操作。

我正在使用 @Autowired 连接存储库并将其传递到数百个线程中,这些线程将 从数据库中搜索并保存到 数据库。

我收到连接异常提示,但是当我通过 pgAdmin4

检查连接时

问题

  1. 为什么连接这么高,而idle几乎占用了所有连接?
  2. 是不是每次在Hibernate中运行,我都会创建一个连接?是否有官方文档详细说明此设计?
  3. 在 Hibernate 中有什么方法可以释放闲置的东西吗?
  4. 或者实际上我应该研究另一个地方而不是 Hibernate?

已更新

我通过缓存 java 代码中的数据来避免频繁搜索和保存 来解决这个问题,但是上面的问题仍然存在。

任何帮助将不胜感激;)

当使用JPA/Hibernate时,你必须设置一个DataSource,这通常是一个使用连接池的实现,这样它就不必一直重新创建连接。相反,将采用连接池中的现有连接。

Spring 提供并支持多种实现,例如 HikariCP、DBCP、Tomcat 等。默认情况下,Springboot1.x使用Tomcat连接池,而Springboot2.x使用HikariCP.

您可以通过设置 minimumIdle 属性 来配置最小空闲连接数。默认情况下,这与 maximumPoolSize 相同,后者又默认为 10。这意味着 Hikari 默认情况下将尝试保持 10 个连接,无论是否空闲。

在 Spring 引导中,您可以使用 spring.datasource.hikari.* 前缀配置 HikariCP 属性,例如:

spring.datasource.hikari.minimumIdle=10
spring.datasource.hikari.maximumPoolSize=10

引用 relevant documentation:

This property controls the minimum number of idle connections that HikariCP tries to maintain in the pool. If the idle connections dip below this value and total connections in the pool are less than maximumPoolSize, HikariCP will make a best effort to add additional connections quickly and efficiently. However, for maximum performance and responsiveness to spike demands, we recommend not setting this value and instead allowing HikariCP to act as a fixed size connection pool. Default: same as maximumPoolSize

如您所见,建议不要更改此行为,因此,如果您使用 HikariCP 在您的应用程序未使用时看到大量空闲连接,这是很正常的。但是,除非另有配置,否则每个应用程序最多应该有 10 个连接。他们还建议将最大池大小保持尽可能小,如 About Pool Sizing 文章中所述。

此外,您可以通过配置 idleTimeout 设置来配置空闲时保持连接的时间。

在@g00glen00b 的帮助下,我检查了 Spring Boot 依赖项,发现 Tomcat 8.5.11 实际上被 Spring Boot 使用。

tomcat 使用属性 maxIdle & minEvictableIdleTimeMillis 来控制允许的空闲连接数以及它们在被逐出之前可以保留多长时间。它的默认值是 maxActive: 100 直接解释了一切。

而在Spring启动时,您可以将此属性管理为spring.datasource.tomcat.max-idle=50

但是正如@g00glen00b 所提到的,直接管理这个值可能并不好,这可能会损害性能。应根据系统本身谨慎使用,并有明确的意图。

在我的例子中,我没有触及它们,我重构了我的 java 代码来缓存数据以减少 java 端的连接。