【问题标题】:Connections are not closed and piling up when running @SpringBootTest classes运行@SpringBootTest 类时连接没有关闭和堆积
【发布时间】:2021-12-01 21:39:05
【问题描述】:

我们有 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


    【解决方案1】:

    事实证明,几乎每个测试类都重新创建了上下文,因为我在测试中广泛使用了@MockBean 注释。由于它会影响 Spring 上下文,因此不同测试类中的每个 @MockBean/No MockBean 组合都算作不同的上下文,即:

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

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

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

    它的唯一目的是声明尽可能多的 MockBean 和/或 SpyBean,以便在类似的测试配置中重复使用。我用TestMockBeans 扩展了相应的测试类,然后,因为它们共享这种相似的设置,Spring 将它们的上下文识别为相似,并且不会为每个测试类重新创建一个新的。

    您可以猜到,并非我在整个 Spring Boot 应用程序中的所有测试都对 Mockbeans 有相同的需求(或没有 Mockbeans),因此这只是部分解决方案,但我希望它可以帮助遇到相同问题的人缓解它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      • 1970-01-01
      • 2017-04-02
      • 2018-12-28
      • 2019-06-26
      • 1970-01-01
      • 2016-08-11
      相关资源
      最近更新 更多