irpas技术客

Spring Cloud 出现No instances available for user-service异常_Cloud-Future

大大的周 893

项目场景:

使用Spring Cloud Alibaba使用Nacos作为注册中心,从order-service订单服务调用user-service用户服务。

启动两个服务,访问nacos的web控制台,两个服务均能正确注册到Nacos。

使用的Spring Cloud Alibaba版本:

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.5.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency>

Nacos版本:?2.0.0-BETA,运行在一台物理机上。

user-service和order-service运行在同一台物理机。与nacos不在一台机器,但在一个局域网内。


问题描述:

当在order-service中调用user-service中的接口时,出现如下错误:

2021-02-20 14:18:57.099 INFO 5292 --- [nio-8011-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client user-service initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=user-service,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:com.alibaba.cloud.nacos.ribbon.NacosServerList@19ec1163 2021-02-20 14:18:57.135 ERROR 5292 --- [nio-8011-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for user-service] with root cause java.lang.IllegalStateException: No instances available for user-service at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:119) ~[spring-cloud-netflix-ribbon-2.2.5.RELEASE.jar:2.2.5.RELEASE] at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:99) ~[spring-cloud-netflix-ribbon-2.2.5.RELEASE.jar:2.2.5.RELEASE]

?order-service调用user-service的代码:

@GetMapping("/order/create") public String newOrder(long userId,String goodsId,int count){ Object user = restTemplate.getForObject("http://user-service/user/info?userId={userId}", Object.class, Collections.singletonMap("userId", userId)); System.out.println(user); System.out.println("生成订单,商品id:"+goodsId+",数量:"+count); return "ok"; }
原因分析:

首先排除法分析原因:

1、排除服务未成功注册到nacos,因为通过Nacos的web控制台可以看到已经成功注册服务。

2、排除RestTemplate类未加@LoadBalanced注解,再三确认RestTemplate Bean加了这个注解,此注解使用Ribbon进行服务调用负载均衡,通过上边的日志看出Ribbon是生效的。

3、通过Nacos提供的api,http://ip:8848/nacos/v1/ns/instance/list?serviceName=user-service,发现user-service服务列表为空,如下:

?发现hosts为空,问题就出在这,服务从注册中心拉取其他服务的注册信息时,使用的就是这个接口,获取不到user-service的注册信息,在调用接口时Ribbon负责将url中的user-servicel替换成实例的ip地址和端口,发现没有该服务的实例,所以抛出了No instances available for user-service异常。同时查看上边的日志也可以看到这句:

DynamicServerListLoadBalancer for client user-service initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=user-service,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:com.alibaba.cloud.nacos.ribbon.NacosServerList@19ec1163

这句日志是info级别的,一般情况谁会在意info级别的日志。仔细看发现current list of Servers=[],为空,和通过接口查询的结果一致。

根本原因找到了,是Nacos提供的拉取服务信息的接口返回的数据不对。

那到底是什么原因导致的这个问题?


解决方案:

仔细查看Nacos中注册的服务信息,发现注册的服务ip地址不对,如下图:

我本机的IP地址是192.168.0.104这个192.168.60.1哪来的?

执行ipconfig:

发现服务注册的ip使用了VMware的虚拟网络。没有使用192.168.0.104的局域网,相当于多块网卡,在进行服务注册时候,选中了VMware虚拟网络。

将服务注册的ip改成192.168.0.104这个,使Nacos和服务之间在一个网段,方法如下:

在服务的application.yml中,加入配置:

spring.cloud.inetutils: preferred-networks=192.168.0 #服务注册时优先使用这个网段。

重启服务,然后重试,一切OK!

调用Nacos的openAPI,http://192.168.0.105:8848/nacos/v1/ns/instance/list?serviceName=user-service

?


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Spring #Cloud #出现No #instances #available #for #userservice异常 #项目场景使用Spring