Spring Boot @ImportTestcontainers在Github Actions执行测试失败
问题诊断与解决方案
问题根源
你遇到的too many clients already错误,核心原因是Github Actions上测试并行执行时,共享的PostgreSQL容器连接数被耗尽:
- 容器定义在接口的
companion object中,属于静态成员,所有测试类会共享同一个PostgreSQL容器实例 - Github Actions默认并行运行多个测试类,每个测试都会创建独立的R2DBC连接池,叠加后总连接数超过PostgreSQL默认的
max_connections限制(默认通常为100) - 本地逐个运行测试时,连接数不会累积,因此不会触发该问题
具体修复方案
1. 调高PostgreSQL容器的最大连接数
修改容器定义,启动时指定更大的max_connections参数:
interface ContainersConfig{ companion object{ @Container @ServiceConnection val postgresSQLContainer = PostgreSQLContainer("postgres:15") .withCommand("postgres -c max_connections=500") } }
2. 限制R2DBC连接池大小
在测试配置文件(如application-test.yml)中,缩小连接池的最大连接数,避免单个测试占用过多连接:
spring: r2dbc: pool: max-size: 20 initial-size: 5
3. 禁止测试并行执行
如果以上方案仍未解决问题,可以强制测试串行执行:
- Gradle:在
build.gradle.kts中添加tasks.test { maxParallelForks = 1 } - Maven:在
pom.xml中配置<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <parallel>none</parallel> </configuration> </plugin> </plugins> </build> - Github Actions:在测试命令后追加参数,例如
./gradlew test --no-parallel
4. 改为每个测试类使用独立容器(可选)
若不想共享容器,可将容器定义从companion object移至测试类内部,每个测试类创建独立容器:
@Testcontainers @SpringBootTest class MyTest { @Container @ServiceConnection val postgresSQLContainer = PostgreSQLContainer("postgres:15") // 测试代码 }
注:此方式会增加测试总耗时,因为每个测试都需要启动新容器。
内容的提问来源于stack exchange,提问作者Hantsy
相关产品推荐
相关产品推荐

