Spring Cloud Alibaba 服务消费者调用 nacos 服务报错:java.net.UnknownHostException: xxx

目录

1. 服务消费者启动类

 1.1. 服务消费者 controller

 2. 服务提供者启动类

2.1. 服务提供者 controller

 3. 服务报错

4. nacos 信息

5. 解决思路

5.1. 配置、注解检查

5.2. 其他方面原因排查

6. 解决方案

7. 参考连接


在 SpringBoot 项目中调用另外的服务报错:

Spring Cloud Alibaba 服务消费者调用 nacos 服务报错:java.net.UnknownHostException: xxx_第1张图片

重点是这一句:

java.net.UnknownHostException: stock-nacos 

意思是未知的主机异常:stock-nacos

stock-nacos 是被调用方。

项目架构如下:

框架 版本号
Spring Boot    2.6.3
spring.cloud.alibaba
2021.0.1.0
spring.cloud
2021.0.1

采用 RestTemplate 进行服务之间的调用,配置负载均衡注解,代码如下:

1. 服务消费者启动类

package com.dake.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
// 在spring cloud 现在的新版本中不需要添加了
@EnableDiscoveryClient
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    // 通常写在配置类中,但是示例的话就这样也可以
    // LoadBalanced注解是告诉该服务调用对方服务时使用负载均衡策略调用,没有此注解则调用时会报500的错误响应码
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
//    public RestTemplate restTemplate(RestTemplateBuilder builder ) {
        // 可以 new RestTemplate,但是官方推荐 RestTemplateBuilder 构造器來构造,提现了构造者模式的设计思想
        // 在这里可以设置超时时间等属性,这里先不设置
        return new RestTemplate();
//        return builder.build();
    }
}

 1.1. 服务消费者 controller

package com.dake.order.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    RestTemplate restTemplate;

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

    @Value("${server.port}")
    private String port;

    @RequestMapping("/add")
    public String add() {
//        String msg = restTemplate.getForObject("http://localhost:8021" + "/stock/reduct", String.class);
        String msg = restTemplate.getForObject(serviceUrl + "/stock/reduct", String.class);
        System.out.println("---------下单成功---------");
        return "Hello World " + msg + ":" + port;
    }
}

 2. 服务提供者启动类

package com.dake.stock;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class StockApplication {

    public static void main(String[] args) {
        SpringApplication.run(StockApplication.class, args);
    }
}

2.1. 服务提供者 controller

package com.dake.stock.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/stock")
public class StockController {

    @RequestMapping("/reduct")
    public String reduct() {
        System.out.println("---------扣减库存---------");
        return "扣减库存";
    }
}

 3. 服务报错

通过 URL 调用服务消费者的 controller 报错:

报错信息,参见文章开头。

4. nacos 信息

我们 nacos 配置完成,1个服务消费者实例和2个服务提供者实例均已注册到 nacos 中。

Spring Cloud Alibaba 服务消费者调用 nacos 服务报错:java.net.UnknownHostException: xxx_第2张图片

 关于 nacos 的配置检查完毕,没有发现有问题。

5. 解决思路

5.1. 配置、注解检查

我们要看是否缺少了注解、配置,或者配置错误,检查完毕之后没有发现有什么问题。

有文章说需要在 RestTemplate 上添加 @LoadBalanced 注解。如果我们去看我的服务消费者启动类,就会发现,该注解我们是有的。

还有人说是 需要在启动类上添加注解 @EnableDiscoveryClient 。实际上,在新版本的 Spring Cloud Alibaba 中,该注解不使用一样可以实现服务注册与发现功能。我们在下文会演示不添加该注解是否可以自动实现服务注册于发现。

5.2. 其他方面原因排查

到了这里,还是解决不了问题。此时不得不去考虑,是否是 SpringBoot版本、 Spring Cloud 与 Spring Cloud Alibaba 版本兼容问题。通过官网我们发现我们使用的版本兼容性没有问题,我们也不用去想我们发现了什么 bug 之类的奇思妙想。

还有人说是 JDK 版本兼容问题。这个有可能,我使用的是 JDK 17,这个倒是有可能,但是我将 JDK 版本降低之后发现还是同样的错误。

我们排除了各种原因之后,还是解决不了问题,那这个可能就麻烦了。

我通过翻看自己之前的项目,也去网上找了 Spring Cloud Alibaba 的教程,也没有发现问题。

就这样,没有办法了,这个项目的演示就耽搁这里了。

6. 解决方案

过了一阵子,我回头继续看这个问题,还是同样的错误。但是这次我们尝试了不同的检索方式,最终让我找到了一个解决方案:

服务消费方的 pom 文件中添加依赖:


    org.springframework.cloud
    spring-cloud-starter-loadbalancer

 找到的参考文章中没有提到在服务消费者还是服务提供者的 pom 中添加该依赖,我个人感觉应该是服务消费者 ,因为它添加的是负载均衡的依赖,而 nacos 自带的 Ribbon 是一个客户端负载均衡,意思就是谁调用就谁来决定负载均衡策略。当然还有服务端负载均衡策略,如F5、HA等,这不在本文的讨论范围,感兴趣者可以自行查阅资料。

我门就在服务消费者的 pom 中添加了以上依赖,刚开始可能是项目编译问题,没有成功,我将服务提供者的 pom 中也添加了该依赖,重新编译后调用成功了。但是这里我们不清楚真正加在哪里,我们去除了 服务消费者的该依赖,结果调用失败。这也证明了是需要添加在 服务消费者的pom 中。但是,这不一定正确,因为我们之前也在服务提供者中也添加了该依赖,下面我们去除服务提供者中的依赖,最终如图:

Spring Cloud Alibaba 服务消费者调用 nacos 服务报错:java.net.UnknownHostException: xxx_第3张图片

 启动项目,重新调用,成功:

Spring Cloud Alibaba 服务消费者调用 nacos 服务报错:java.net.UnknownHostException: xxx_第4张图片

7. 参考连接

Spring Cloud:负载均衡 - Spring Cloud Loadbalancer原理 

(已解决)nacos+RestTemplate使用服务名报异常java.net.UnknownHostException

你可能感兴趣的:(Spring,Cloud,Alibaba,java,spring,cloud,spring,boot)