详解SpringCloud Ribbon 负载均衡通过服务器名无法连接的神坑

时间:2021-05-19

一,问题

采取eureka集群、客户端通过Ribbon调用服务,Ribbon端报下列异常

java.net.UnknownHostException: SERVICE-HIjava.lang.IllegalStateException: No instances available for SERVICE-HIjava.lang.IllegalStateException: Request URI does not contain a valid hostname: http://SERVICE-HIcom.netfix.discovery.shared.taransport.TransportException: Cannot execute request on any known server

Spring Cloud版本比较乱,版本关联引用更是乱,最终我切换到<spring-cloud.version> Greenwich.SR1 </spring-cloud.version> 异常为: No instances available for SERVICE-HI

二、寻找答案

网上答案千奇百怪

1,Spring Cloud 官网,RestTemplate bean配置中添加负载均衡注解@LoadBalanced,我添加了

@Bean@LoadBalancedpublic RestTemplate getRestTemplate(){ return new RestTemplate();}

结果无效仍然一样报错

2,访问的服务名名称不能有下划线:

我的名称是“SERVICE-HI”本身就不存在下划线,所以不考虑这条。

3,主机名称没在系统文件hosts中配置,ping不通你服务名:

很扯的答案,为什么要配host,负载多台机器让主机名指向谁?不考虑此答案

三,分析问题

百度不到,自己分析原因,发现ribbon服务器没有注册到eureka server中

分析原理:我的客户端服务“SERVICE-HI”已经成功注册到eureka server中了,如果ribbon服务器不在eureka server中注册,是不会知道客户端服务“SERVICE-HI”的存在以及它存在的位置,那么结论就是,因为ribbon服务器没有在eureka server中注册成功,所以不能识别主机名称。

四,解决问题

配置文件

eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/server: port: 8764spring: application: name: service-ribbon

依赖导入

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

主程序注释

@SpringBootApplication@EnableDiscoveryClientpublic class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run( ServiceRibbonApplication.class, args ); }}

有问题,最终发现@EnableDiscoveryClient标签无法注册到注册中心,百度@EnableDiscoveryClient,得到的结论是

@EnableDiscoveryClient和@EnableEurekaClient一样,能够让注册中心能够发现,扫描到改服务,不同点:@EnableEurekaClient只适用于Eureka作为注册中心,@EnableDiscoveryClient可以是Eureka或其他(consul、zookeeper等)注册中心 。

具体原因不去分析,这里先直接切换为@EnableEurekaClient注释

@EnableEurekaClient在哪个包里简直是迷一样的存在,不同版本的spring cloud 中位置不同,我使用Greenwich.SR1,需要引入下面的包

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

修改主程序注释

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.hystrix.EnableHystrix;@SpringBootApplication@EnableEurekaClient@EnableHystrix //我开启了段容器public class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run( ServiceRibbonApplication.class, args ); }}

这里提一句在 Greenwich.SR1中段容器在下面包中

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

重新启动ribbon,发现控制台输入

2019-06-15 13:08:06.668 INFO 14796 --- [ main] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server2019-06-15 13:08:06.878 INFO 14796 --- [ main] com.netflix.discovery.DiscoveryClient : The response status is 2002019-06-15 13:08:06.882 INFO 14796 --- [ main] com.netflix.discovery.DiscoveryClient : Starting heartbeat executor: renew interval is: 302019-06-15 13:08:06.886 INFO 14796 --- [ main] c.n.discovery.InstanceInfoReplicator : InstanceInfoReplicator onDemand update allowed rate per min is 42019-06-15 13:08:06.891 INFO 14796 --- [ main] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1560575286889 with initial instances count: 22019-06-15 13:08:06.894 INFO 14796 --- [ main] o.s.c.n.e.s.EurekaServiceRegistry : Registering application SERVICE-RIBBON with eureka with status UP2019-06-15 13:08:06.896 INFO 14796 --- [ main] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=1560575286896, current=UP, previous=STARTING]2019-06-15 13:08:06.900 INFO 14796 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SERVICE-RIBBON/DESKTOP-FJQITE3:service-ribbon:8764: registering service...2019-06-15 13:08:06.958 INFO 14796 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SERVICE-RIBBON/DESKTOP-FJQITE3:service-ribbon:8764 - registration status: 2042019-06-15 13:08:06.961 INFO 14796 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8764 (http) with context path ''2019-06-15 13:08:06.963 INFO 14796 --- [ main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 87642019-06-15 13:08:06.967 INFO 14796 --- [ main] cn.meylink.ServiceRibbonApplication : Started ServiceRibbonApplication in 5.868 seconds (JVM running for 7.204)

查看Eureka

浏览器测试访问成功!!!

五,附件:Greenwich.SR1 版中常用依赖

有好多问题都是因为 不同版本中引入不正确的依赖导致,这里列出Greenwich.SR1版中常用依赖,这里都不需要指定版本号

<dependencies> <!-- eureka client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- eureka server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!-- 段容器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <!-- ribbon --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <!-- feign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- config server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!-- config client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- zuul --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency></dependencies>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章