【问题标题】:Microservices - RestTemplate UnknownHostException微服务 - RestTemplate UnknownHostException
【发布时间】:2016-09-06 16:18:04
【问题描述】:

我有一个简单的设置,其中包含一个 Eureka 服务注册服务器、一个公共 API 服务和一个使用 RestTemplate 从公共 API 调用的服务。 Eureka告诉我服务注册成功了,但是当我调用服务时

@Service
public class MyServiceService {

    @Autowired
    private RestTemplate restTemplate;

    private final String serviceUrl;

    public MyServiceService() {
        this.serviceUrl = "http://MY-SERVICE";
    }

    public Map<String, String> getTest() {

        Map<String, String> vars = new HashMap<>();
        vars.put("id", "1");

        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());

        return restTemplate.postForObject(serviceUrl+"/test", "", Map.class, vars);
    }
}

我得到以下异常

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed;
  nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://MY-SERVICE/test": MY-SERVICE;
  nested exception is java.net.UnknownHostException: MY-SERVICE] with root cause java.net.UnknownHostException: MY-SERVICE

我创建了一个示例项目来说明我的设置,也许有人可以看看它并告诉我我的设置有什么问题。

https://github.com/KenavR/spring-boot-microservices-example

谢谢

【问题讨论】:

  • 看起来好像注入的RestTemplate 不是负载平衡的。由于您在项目中使用 Spring Cloud Angel.SR6,它应该自动注入负载均衡的。我能想到的唯一建议是用@LoadBalanced 注释您的RestTemplate,看看这是否会有所不同。
  • 我过去和现在都试过了,遗憾的是错误保持不变。
  • 你试过Spring Cloud Brixton.RELEASE吗,今天发布了。请注意,使用 Brixton,您必须定义自己的 @LoadBalanced @Bean RestTemplate,因为默认情况下 Brixton 不再创建一个。然后你可以像往常一样@Autowire它。除此之外,您可以尝试使用小写 http://my-service/test 的服务 ID 调用您的服务。
  • 切换到 Brixton 并更改代码需要解决问题,谢谢

标签: java spring-boot spring-cloud microservices netflix-eureka


【解决方案1】:

正如patrick-grimard 所建议的,切换到 Brixton 并更改代码需要解决问题。工作解决方案在Github

还将发布的id 从请求参数更改为请求正文,这也改变了我将其添加到请求中的方式。

服务端点

@RequestMapping(method = RequestMethod.POST, produces = "application/json; charset=utf-8")
public @ResponseBody Map<String, String> getTest(@RequestBody Map<String, Long> params) {

    Map<String, String> response = new HashMap<>();

    response.put("name", "My Service");

    return response;
}

RestTemplate 创建

@Configuration
public class PublicAPIConfiguration {
    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

呼叫服务

@Service
public class MyServiceService {

    @Autowired
    private RestTemplate restTemplate;

    private final String serviceUrl;

    public MyServiceService() {
        this.serviceUrl = "http://my-service";
    }

    public Map<String, String> getTest() {

        Map<String, Long> vars = new HashMap<>();
        vars.put("id", 1L);

        return restTemplate.postForObject(serviceUrl+"/test", vars, Map.class);
    }
}

【讨论】:

  • 你能说得更具体点吗?是否与 Spring 版本有关?
  • 我有类似的问题。我的服务一直在使用 RestTemplate 通过myhost.com 与另一个服务通信。虽然,我们没有改变任何东西,它开始抛出 UnknownHostException。 ping myhost.com 没问题。
【解决方案2】:

对于将来可能碰巧遇到此问题的任何人,我有完全相同的堆栈跟踪,但解决方案略有不同。

从编码的角度来看,我的问题与配置无关。它与我运行代码的服务器有关。我忽略了它位于没有 DNS 的 DMZ 上的事实,因此您必须手动将域映射到 IP。

或多或少,请确保您的 DNS 在您的服务器上正确配置,因为从 restTemplate 的角度来看,它会抛出这个确切的堆栈跟踪。

【讨论】:

    【解决方案3】:

    @LoadBalanced 添加到RestTemplate bean 创建对我有用

    【讨论】:

      猜你喜欢
      • 2017-12-29
      • 2020-04-10
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      • 2022-01-22
      • 2020-11-28
      • 2022-01-24
      • 1970-01-01
      相关资源
      最近更新 更多