微服务 - RestTemplate UnknownHostException

5

我有一个简单的设置,包括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 谢谢。

1
看起来被注入的 RestTemplate 不是负载均衡的。由于您在项目中使用了 Spring Cloud Angel.SR6,它应该会自动注入负载均衡的 RestTemplate。我唯一能想到的建议是给您的 RestTemplate 加上 @LoadBalanced 注解,看看是否有所不同。 - Patrick Grimard
我曾经尝试过,现在又再次尝试,但遗憾的是错误仍然存在。 - KenavR
2
你尝试过Spring Cloud Brixton.RELEASE吗?它是今天发布的。只需注意,在Brixton中,您必须自己定义 @LoadBalanced @Bean RestTemplate,因为Brixton不再默认创建一个。然后,你可以像往常一样进行 @Autowire。除此之外,你也可以尝试使用小写的服务ID来调用你的服务,如http://my-service/test - Patrick Grimard
转换到Brixton并更改必要的代码解决了问题,谢谢。 - KenavR
3个回答

9

根据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 版本有关吗? - valijon
我有类似的问题。我的服务一直在使用RestTemplate与http://myhost.com上的另一个服务进行通信。尽管我们没有更改任何内容,但它开始抛出UnknownHostException异常。ping myhost.com是正常的。 - valijon

1

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

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

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


0

RestTemplate bean的创建中加入@LoadBalanced对我很有效


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接