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

Spring Boot与Eureka环境下java.net.UnknownHostException报错修复

解决非Spring Boot客户端通过RestTemplate调用Eureka注册服务时的UnknownHostException问题

看起来你遇到的核心问题是:你的客户端不是Spring Boot应用,因此Spring Cloud的自动配置机制没有生效——即便给RestTemplate加了@LoadBalanced注解,它也不会自动具备服务名解析能力。下面是具体的排查和解决步骤:

1. 确认依赖是否齐全

首先要确保项目引入了服务发现和负载均衡的必要Spring Cloud依赖:

  • 若使用Spring Cloud 2020.0.0(Ilford)及以后版本,推荐引入spring-cloud-starter-loadbalancer(替代旧版Ribbon)
  • 必须引入spring-cloud-starter-netflix-eureka-client来连接Eureka Server

Maven依赖示例:

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

2. 手动配置具备负载均衡能力的RestTemplate

非Spring Boot应用不会自动加载LoadBalancerAutoConfiguration,所以需要手动给RestTemplate添加负载均衡拦截器,让它能通过服务名从Eureka获取实例地址:

import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;

@Configuration
public class RestTemplateConfig {

    @Bean
    public LoadBalancerClient loadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory) {
        return new org.springframework.cloud.client.loadbalancer.DefaultLoadBalancerClient(loadBalancerClientFactory);
    }

    @Bean
    public LoadBalancerClientFactory loadBalancerClientFactory() {
        LoadBalancerClientFactory factory = new LoadBalancerClientFactory();
        // 配置默认轮询负载均衡策略(可选)
        factory.setConfigurations(Collections.singletonList(new org.springframework.cloud.loadbalancer.core.DefaultLoadBalancerConfiguration()));
        return factory;
    }

    @Bean
    @Primary // 若存在多个RestTemplate实例,标记此为默认
    public RestTemplate loadBalancedRestTemplate(LoadBalancerClient loadBalancerClient) {
        RestTemplate restTemplate = new RestTemplate();
        // 添加负载均衡拦截器,让RestTemplate能解析服务名
        restTemplate.setInterceptors(Collections.singletonList(new LoadBalancerInterceptor(loadBalancerClient)));
        return restTemplate;
    }
}

3. 正确配置Eureka客户端

确保配置类启用服务发现,并配置Eureka Server地址:

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableDiscoveryClient // 启用通用服务发现(替代@EnableEurekaClient)
public class EurekaConfig {
}

然后在application.properties中添加Eureka配置:

# Eureka Server地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
# 若客户端无需注册到Eureka,仅需发现服务,设置为false
eureka.client.register-with-eureka=false
# 定期拉取服务注册表
eureka.client.fetch-registry=true

4. 验证服务发现是否正常

在发起请求前,可先验证客户端是否能从Eureka获取目标服务:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;

@Component
public class ServiceChecker {

    @Autowired
    private DiscoveryClient discoveryClient;

    public void verifyServiceExists() {
        boolean serviceExists = discoveryClient.getServices().contains("documents-microservice");
        if (serviceExists) {
            System.out.println("目标服务已在Eureka中注册");
            // 打印具体实例地址
            discoveryClient.getInstances("documents-microservice").forEach(instance -> {
                System.out.println("实例地址:" + instance.getUri());
            });
        } else {
            System.err.println("未从Eureka获取到documents-microservice服务");
        }
    }
}

5. 确保Spring上下文正确初始化

非Spring Boot应用需要手动初始化Spring上下文,确保所有配置类被扫描到:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpEntity;
import org.springframework.web.client.RestTemplate;

public class ClientApplication {
    public static void main(String[] args) {
        // 加载配置类,初始化Spring上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
                EurekaConfig.class,
                RestTemplateConfig.class,
                ServiceChecker.class
        );

        // 先验证服务可用性
        ServiceChecker checker = context.getBean(ServiceChecker.class);
        checker.verifyServiceExists();

        // 使用具备负载均衡的RestTemplate发起请求
        RestTemplate restTemplate = context.getBean(RestTemplate.class);
        HttpEntity<String> entity = new HttpEntity<>("请求体内容"); // 替换为你的请求实体
        ResponseEntity<String> response = restTemplate.exchange(
                "http://documents-microservice/document-name",
                HttpMethod.POST,
                entity,
                String.class
        );
    }
}

关键总结

非Spring Boot应用无法享受Spring Boot的自动配置红利,必须手动完成以下操作:

  • 引入必要的Spring Cloud依赖
  • 配置LoadBalanced相关Bean,给RestTemplate添加负载均衡拦截器
  • 启用服务发现并正确配置Eureka地址

这样RestTemplate就能正常解析服务名,从Eureka获取实例地址发起请求了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:12:29