You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot容器与Mock Server同网络通信失败问题排查

Spring Boot容器(Testcontainers GenericContainer)无法同网络下的WireMock Mock Server通信

问题描述

我使用Testcontainers的GenericContainer运行Spring Boot镜像data-retriever,期望该容器能消费同网络下WireMock Mock Server返回的模拟数据,编写了如下测试类:

@Slf4j
public class TestContainer {


    private static final Network network = Network.newNetwork();

    private static final WireMockContainer wiremockServer = new WireMockContainer("wiremock/wiremock:2.35.0")
            .withNetwork(network)
            .withNetworkAliases("mockServer")
            .withMappingFromResource("weatherMock", "MockData/weatherMock.json")
            .withMappingFromResource("locationMock", "MockData/locationMock.json");

    private static final GenericContainer springBootContainer = new GenericContainer(DockerImageName.parse("data-retriever"))
            .withNetwork(network);


    @Autowired
    @Qualifier("defaultRestTemplate")
    RestTemplate restTemplate;

    @Before
    public void setUpMockServers() {
        wiremockServer.start();

        springBootContainer.dependsOn(wiremockServer)
                .withImagePullPolicy(PullPolicy.defaultPolicy())
                .withExposedPorts(20100)
                /* update the spring properties using environment variables and make the spring talk to mock server*/
                .withEnv("weather_data_host", wiremockServer.getBaseUrl()) 
                .withEnv("location_data_host", wiremockServer.getBaseUrl())
                .withStartupTimeout(Duration.of(5, ChronoUnit.MINUTES));

        springBootContainer.start();

    }

    @After("@testContainer")
    public void stopContainer() {
        wiremockServer.stop();
        springBootContainer.stop();
    }

    @Given("I am mock dependency using wiremock testcontainers")
    public void iAmMockDependencyUsingWiremockTestcontainers() {

        log.info("dataIngestion server host: {}", springBootContainer.getHost());
        log.info("dataIngestion server port: {}", springBootContainer.getFirstMappedPort());
        String url = String.format("https://%s:%s/retrieveData", springBootContainer.getHost(), springBootContainer.getFirstMappedPort());
        var response = restTemplate.getForEntity(url, Object.class);
        Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
       
    }
}

运行测试时,data-retriever容器无法与Mock Server容器通信,但通过Postman能正常访问Mock Server获取模拟数据。我使用wiremockServer.getBaseUrl()获取Mock Server的主机和端口并传入Spring容器的环境变量。

疑问

  1. 为何同网络下data-retriever容器无法与Mock Server容器通信?
  2. 是否需要进行额外配置?

解决方案

问题原因

核心问题是误用了wiremockServer.getBaseUrl():这个方法返回的是宿主机(本地机器)的IP加上WireMock容器映射到宿主机的端口,而Docker容器之间在同一自定义网络内通信时,必须使用容器的网络别名+容器内部的端口,而非宿主机的映射地址。

WireMock容器默认内部端口为8080(你使用的2.35.0版本遵循此默认值),且你已经给WireMock容器设置了网络别名mockServer,所以Spring Boot容器内部必须用http://mockServer:8080作为Mock Server的访问地址。

具体修改

修改Spring Boot容器的环境变量配置,替换错误的地址:

// 原代码
.withEnv("weather_data_host", wiremockServer.getBaseUrl()) 
.withEnv("location_data_host", wiremockServer.getBaseUrl())

// 修改后
.withEnv("weather_data_host", "http://mockServer:8080") 
.withEnv("location_data_host", "http://mockServer:8080")

额外检查点

  • 确认Spring Boot应用中是否正确读取这两个环境变量,确保请求Mock Server的URL是基于http://mockServer:8080构建的,而非硬编码的其他地址。
  • 若自定义过WireMock的内部端口,需将上述地址中的8080替换为自定义端口。
  • 查看Spring Boot容器的日志,若仍有问题,可通过日志中的连接超时、DNS解析失败等信息进一步定位问题。

关于额外配置的疑问

不需要额外的网络配置:你已经创建了自定义网络并让两个容器加入该网络,同时设置了WireMock的网络别名,只要地址使用正确,容器之间就能正常通信。


内容的提问来源于stack exchange,提问作者Golden Heart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:05:02