运行@SpringBootTest类时连接未关闭并堆积

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

我们有 Spring Boot 集成测试,并定期编写新的测试。 我注意到数据库连接不断堆积:我运行的测试越多,我的 PostgreSQL 实例的连接峰值就越高。

在运行所有测试时,Spring Boot 请求的连接数超过 300 个,并且构建开始失败(我们的

max_connection
设置为 300)。

经过一些研究,我了解到运行测试后连接不会被释放,因为 Spring Boot 测试:如果上下文没有显式销毁,连接不会关闭。

我觉得这很奇怪,但尝试使用

@DirtiesContext
来证明一点,在我们所有的测试类上,它确实在某种意义上解决了问题,避免了峰值(一次不超过 30 个连接,不会堆积到300 像以前一样),但由于此注释强制在每个测试类之前重新创建上下文,因此构建速度变慢了很多,而且我发现每次都需要重新创建 Spring 上下文以确保连接正确关闭,这并不是很令人满意。

数据源是一个

HikariDataSource
,使用配置类进行配置。

我发现的另一个解决方法是更改 Hikari 的最大池大小。我将其设置为低于默认值 10(我不确定为每个测试类保留 10 个连接是否有用)。当我运行所有测试时,此更改有效地降低了连接总数,但它们仍在堆积(只是更低!)

我想我错过了一些东西,如何确保每个测试类后连接都关闭?一定有比

@DirtiesContext
更好的方法,我就是找不到。感谢您的帮助。

spring postgresql spring-boot hikaricp
2个回答
9
投票

事实证明,几乎每个测试类都重新创建了上下文,因为我在测试中广泛使用了

@MockBean
注释。由于它会影响 Spring 上下文,因此不同测试类中的每个
@MockBean
/No MockBean 组合都算作不同的上下文,即:

  • 测试类1:bean MyService是MockBean,MyOtherService不是
  • 测试类2:bean MyService是一个MockBean,MyOtherService也是一个MockBean
  • 测试类3:这两个bean都不是MockBean

在这种情况下,由于bean配置不同,将为每个类创建一个新的Spring上下文,从而导致与数据源的连接数量不断增加。

为了(部分)解决这个问题,我在测试类的 beans 组合中寻找模式,并创建了一个名为

TestMockBeans
的新类。

其唯一目的是声明尽可能多的 MockBean 和/或 SpyBean 以便在类似的测试配置中重用。我使用

TestMockBeans
扩展相应的测试类,然后,因为它们共享相似的设置,Spring 将它们的上下文识别为相似的,并且不会为每个测试类重新创建一个新的上下文。

正如您所猜测的,并非我在整个 Spring boot 应用程序中的所有测试都对 Mockbeans 具有相同的需求(或缺少 Mockbeans),因此这只是部分解决方案,但我希望它能帮助遇到相同问题的人减轻问题。


0
投票

限制上下文刷新的解决方法也是很有价值的建议。 但我必须在测试之间的 Spring 重新初始化期间限制连接或使它们关闭。

下面链接的建议对我有用,只是限制

spring.datasource.hikari.maximum-pool-size=2

Spring Boot 运行测试时出现“PSQLException: FATAL: 抱歉,已经有太多客户端”

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