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

Spring Eureka无法识别服务实例,跨服务调用失败求助

Eureka服务发现与内部HTTP调用失败解决方案

问题背景

搭建了包含chat-ws、users-ws和discovery-service的微服务集群,尝试从chat-ws向users-ws发起内部HTTP调用时遇到以下问题:

  • 调用discoveryClient.getInstancesById("USERS-WS")或"users-ws"时,实例列表始终为空
  • WebClient调用返回DNS解析失败错误,提示无法解析users-ws
  • Eureka控制台显示USERS-WS和CHAT-WS已正常注册,所有服务均添加了对应注解(@EnableDiscoveryClient、@EnableEurekaServer)

相关代码与错误日志

chat-ws中调用users-ws的代码:

public void getUsersData(List<String> userIds){
        List<InstanceInfo>instance = discoveryClient.getInstancesById("USERS-WS");
        log.info("instances --> " + instance);

        String url = "http://users-ws/api/user/usersdata";
        String json = toJson(userIds);
        log.info("json --> " + json);
        Mono<String> response = webClient
                .post()
                .uri(url)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(json))
                .retrieve()
                .bodyToMono(String.class);

        response.subscribe(
                responseBody ->{
                    log.info("response body --> " + responseBody);
                },
                error -> {
                    log.warn("error --> " + error);
                }
        );

    }

WebClient返回的错误日志:

[id: 0xd2582735] RECEIVED: UDP [55785: /192.168.2.1:53], DatagramDnsResponse(from: /192.168.2.1:53, to: /[0:0:0:0:0:0:0:0]:61795, id: 55785, QUERY(0), NXDomain(3), RD RA)
[ctor-http-nio-1] io.netty.resolver.dns.DnsQueryContext    : [id: 0xd2582735] WRITE: UDP, [47691: /192.168.2.1:53], DefaultDnsQuestion(users-ws. IN CNAME)
[ctor-http-nio-1] io.netty.resolver.dns.DnsNameResolver    : [id: 0xd2582735] RECEIVED: UDP [47691: /192.168.2.1:53], DatagramDnsResponse(from: /192.168.2.1:53, to: /[0:0:0:0:0:0:0:0]:61795, id: 47691, QUERY(0), NXDomain(3), RD RA)
error --> org.springframework.web.reactive.function.client.WebClientRequestException: Failed to resolve 'users-ws' [A(1)] after 2 queries 

各服务配置文件:

discovery-service配置

server.port=8086
spring.application.name=discoveryservice
eureka.instance.hostname=localhost

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.netflix.discovery=DEBUG

chat-service配置

server.port=${PORT:0}

spring.application.name=chat-ws
eureka.client.service-url.defaultZone=http://localhost:8086/eureka
eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}}

eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
eureka.client.enabled=true

gateway.ip=192.168.2.184

logging.level.root=DEBUG

user-service配置

server.port=${PORT:0}

spring.application.name=users-ws
eureka.client.service-url.defaultZone=http://localhost:8086/eureka
eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}}

eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
eureka.client.enabled=true

gateway.ip=192.168.2.184

错误分析

  1. DiscoveryClient方法调用错误:getInstancesById()是根据服务的instance-id查询实例,而非服务名。传入的USERS-WS是Eureka中显示的服务名,不是实例ID,因此无法找到实例。
  2. WebClient未集成服务发现:当前WebClient直接通过DNS解析服务名users-ws,没有利用Eureka的服务发现机制,导致DNS无法识别内部服务名。
  3. 服务名大小写一致性问题:Eureka默认会将spring.application.name转换为大写存储,调用时需匹配该格式。

解决方案

1. 修正DiscoveryClient实例查询方法

将getInstancesById()替换为getInstances(),传入Eureka中注册的服务名(大写USERS-WS):

// 原代码
List<InstanceInfo> instance = discoveryClient.getInstancesById("USERS-WS");
// 修改后
List<InstanceInfo> instances = discoveryClient.getInstances("USERS-WS");

可添加日志验证已注册服务列表,确认是否拉取到目标服务:

log.info("已注册服务列表: " + discoveryClient.getServices());

2. 配置WebClient支持负载均衡与服务发现

在chat-ws中创建WebClient配置类,添加@LoadBalanced注解,让WebClient能够通过Eureka解析服务名:

@Configuration
public class WebClientConfig {
    @Bean
    @LoadBalanced
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }

    @Bean
    public WebClient webClient(WebClient.Builder webClientBuilder) {
        return webClientBuilder.build();
    }
}

确保注入的WebClient是通过该配置类创建的,而非直接实例化。

3. 验证服务名一致性

Eureka控制台显示的服务名为USERS-WS,对应users-ws的spring.application.name=users-ws(Eureka自动转大写),因此调用时使用http://USERS-WS/api/user/usersdata或http://users-ws/api/user/usersdata均可(Eureka服务名大小写不敏感),建议与Eureka显示的大写格式保持一致。

4. 确认注册表拉取配置

确保chat-ws的eureka.client.fetch-registry=true已正确配置,该配置决定服务是否从Eureka拉取注册表信息。若仍有问题,可添加eureka.client.registry-fetch-interval-seconds=5缩短注册表拉取间隔,加速服务发现。

验证步骤

  1. 重启chat-ws和users-ws服务
  2. 调用getUsersData()方法,检查日志是否能获取到users-ws实例
  3. 查看WebClient调用是否成功返回响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:56:02