java.net.UnknownHostException异常

在Springcloud使用RestTemplate访问其他模块的时候,可能会出现java.lang.IllegalStateException: No instances available for localhost问题。在Spring Cloud中集成Spring cloud alibaba的Nacos组件时,当进行微服务请求时会出现如下异常信息:

java.net.UnknownHostException: user-provider
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:196) ~[na:1.8.0_271]
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394) ~[na:1.8.0_271]
	at java.net.Socket.connect(Socket.java:606) ~[na:1.8.0_271]
	at java.net.Socket.connect(Socket.java:555) ~[na:1.8.0_271]

或者如下信息:

java.net.UnknownHostException: nacos-payment-provider
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184) ~[na:1.8.0_131]
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_131]
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_131]
	at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_131]
	at java.net.Socket.connect(Socket.java:538) ~[na:1.8.0_131]

基本环境配置

对应的微服务配置文件为:

server:
  port: 8083


spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848


# 消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

Controller层的使用:

@RestController
@Slf4j
public class OrderNacosController {
    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String serverURL;

    @GetMapping(value = "/consumer/payment/nacos/{id}")
    public String paymentInfo(@PathVariable("id") Long id ){
        return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
    }
}

对应RestTemplate的实例化:

@Configuration
public class ApplicationContextConfig {
    @Bean
    public RestTemplate getRestTemplate(){
        return  new RestTemplate();
    }
}

错误原因分析

在上述示例中,导致错误的原因在于对RestTemplate的实例化过程中,缺少了指定基于Ribbon的负载均衡策略。在实例化RestTemplate的注解上添加@LoadBalanced注解即可,效果如下:

@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return  new RestTemplate();
    }
}

大多数情况下如果是缺失该注解导致的问题,添加上对应的注解即可。RestTemplateCustomizer会给标有@LoadBalance的RestTemplate添加一个拦截器,拦截器的作用就是对请求的URI进行转换获取到具体应该请求哪个服务实例ServiceInstance。

问题还未解决?

如果添加注解还不能够解决问题,此时就要考虑是否是依赖引入的问题了。比如检查一下微服务消费者(consumer)的项目中是否引入了LoadBalance的依赖:

<!-- consumer需要额外添加负载均衡的依赖-->
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-loadbalancer</artifactId>
     <version>${loadbalancer.version}</version>
</dependency>

如果基于Ribbon的负载均衡,那么是否添加了Ribbon的依赖:

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



Spring cloud alibaba nacos异常java.net.UnknownHostException插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://choupangxia.com/2021/05/21/spring-cloud-alibaba-nacos-java-net-unknownhostexception/