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

使用Eureka的HTTP请求未正确填充端口问题排查

问题:Docker容器中WebClient调用Eureka注册服务时默认使用80端口导致连接失败

我通过docker-compose在Docker容器中运行多个服务,尝试从一个服务向另一个服务发起HTTP请求时失败——请求始终使用80端口,而非Eureka中注册的端口。

遍历已发现的应用时,能正确获取到注册信息:

List<Application> applications = discoveryClient.getApplications().getRegisteredApplications();

for (Application application : applications) {
    List<InstanceInfo> applicationsInstances = application.getInstances();
    for (InstanceInfo applicationsInstance : applicationsInstances) {
        String name = applicationsInstance.getAppName();
        String url = applicationsInstance.getHomePageUrl();
        System.out.println(name + ": " + url);
    }
}

输出结果正确:

IDENTITY-SERVICE: http://172.20.0.3:10103/ 

但使用WebClient发起如下请求时:

return webClientBuilder
        .build()
        .post()
        .uri("http://identity-service/api/auth/validate", uriBuilder -> uriBuilder.queryParam("token", "xyz").build())
        .retrieve()
        .bodyToMono(ValidationResponseDTO.class);

抛出异常,显示请求调用的是80端口:

org.springframework.web.reactive.function.client.WebClientRequestException: finishConnect(..) failed: Connection refused: identity-service/172.20.0.3:80

手动指定端口(即http://identity-service:10103/api/auth/validate)时,请求能正常执行。请问为何请求未使用Eureka中注册的端口?


解决方案

问题的核心是你当前的WebClient没有集成Spring Cloud的负载均衡能力,直接用服务名发起请求时,WebClient会将其视为普通域名,通过Docker内部DNS解析到容器IP后,默认使用HTTP的80端口发起请求,而非从Eureka获取注册的端口。

解决步骤:

  • 引入负载均衡依赖
    在你的pom.xml(Maven)或build.gradle(Gradle)中添加Spring Cloud LoadBalancer依赖:
    Maven示例:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    

    Gradle示例:

    implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'
    
  • 配置带负载均衡的WebClient.Builder
    在配置类中声明带有@LoadBalanced注解的WebClient.Builder Bean:

    @Configuration
    public class WebClientConfig {
        @Bean
        @LoadBalanced
        public WebClient.Builder loadBalancedWebClientBuilder() {
            return WebClient.builder();
        }
    }
    
  • 修改请求URI的写法
    使用lb://前缀指定服务名,让负载均衡组件介入,自动从Eureka获取实例的正确端口:

    return webClientBuilder // 这里注入的是带@LoadBalanced的builder
            .build()
            .post()
            .uri("lb://identity-service/api/auth/validate", uriBuilder -> uriBuilder.queryParam("token", "xyz").build())
            .retrieve()
            .bodyToMono(ValidationResponseDTO.class);
    

这样调整后,WebClient会通过Spring Cloud LoadBalancer从Eureka拉取identity-service的注册实例信息,自动使用正确的端口发起请求,无需手动指定端口。


内容的提问来源于stack exchange,提问作者Benedikt J Schlegel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:50:28