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

Spring WebClient忽略baseUrl端口号问题排查求助

问题原因与解决方案

原因

问题出在你使用的LoadBalancedExchangeFilterFunction上。这个过滤器是为服务发现场景设计的:它会把WebClient的baseUrl当作服务名,而非具体的URL地址,然后去服务注册中心(比如Eureka、Nacos)查找对应的服务实例,再替换成实例的实际地址。

在你的测试场景中,你设置的baseUrl是http://localhost:9999,过滤器会把localhost识别成服务名,尝试去注册中心查找这个服务。但测试环境没有启动服务注册中心,过滤器找不到对应的服务实例,就会回退到默认逻辑,直接去掉端口,请求http://localhost/api/schedules,最终导致503错误。

解决方案

有两种简单的处理方式:

1. 测试时移除负载均衡过滤器

在测试类中重新定义ScheduleClient的Bean,不添加LoadBalancedExchangeFilterFunction:

@SpringBootTest
public class ScheduleClientTest {

    @Bean
    ScheduleClient testScheduleClient(@Value("${schedule-service.base-url}") String baseUrl) {
        WebClient webClient = WebClient.builder()
                .baseUrl(baseUrl)
                // 不添加负载均衡过滤器
                .build();

        HttpServiceProxyFactory httpServiceProxyFactory =
                HttpServiceProxyFactory
                        .builder(WebClientAdapter.forClient(webClient))
                        .build();

        return httpServiceProxyFactory.createClient(ScheduleClient.class);
    }

    @DynamicPropertySource
    static void overrideScheduleServiceBaseUrl(DynamicPropertyRegistry registry) {
        registry.add(
                "schedule-service.base-url",
                () -> "http://localhost:9999");
    }

    // 测试方法...
}

2. 给配置类添加环境条件

修改原ScheduleConfig,区分测试与非测试环境的Bean定义:

@Configuration
@RequiredArgsConstructor
public class ScheduleConfig {
    private final LoadBalancedExchangeFilterFunction filterFunction;

    @Bean
    @Profile("!test") // 非测试环境加载带负载均衡的Bean
    ScheduleClient scheduleClient(
            @Value("${schedule-service.base-url}") String baseUrl
    ) {
        WebClient webClient = WebClient.builder()
                .baseUrl(baseUrl)
                .filter(filterFunction)
                .build();

        HttpServiceProxyFactory httpServiceProxyFactory =
                HttpServiceProxyFactory
                        .builder(WebClientAdapter.forClient(webClient))
                        .build();

        return httpServiceProxyFactory.createClient(ScheduleClient.class);
    }

    @Bean
    @Profile("test") // 测试环境加载不带负载均衡的Bean
    ScheduleClient testScheduleClient(
            @Value("${schedule-service.base-url}") String baseUrl
    ) {
        WebClient webClient = WebClient.builder()
                .baseUrl(baseUrl)
                .build();

        HttpServiceProxyFactory httpServiceProxyFactory =
                HttpServiceProxyFactory
                        .builder(WebClientAdapter.forClient(webClient))
                        .build();

        return httpServiceProxyFactory.createClient(ScheduleClient.class);
    }
}

这样测试时会使用不带负载均衡过滤器的WebClient,baseUrl的端口会被正常保留,请求能正确发送到WireMock的9999端口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:45:03