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 项目中调用另外的服务报错:

重点是这一句:

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 中。

 关于 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 文件中添加依赖:

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

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

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

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

7. 参考连接

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

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

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北冥牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值