详解SpringCloud Ribbon 负载均衡通过服务器名无法连接的神坑
一,问题
采取eureka集群、客户端通过ribbon调用服务,ribbon端报下列异常
java.net.unknownhostexception: service-hi java.lang.illegalstateexception: no instances available for service-hi java.lang.illegalstateexception: request uri does not contain a valid hostname: http://service-hi com.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 @loadbalanced public 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: 8764 spring: 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 @enablediscoveryclient public 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 server 2019-06-15 13:08:06.878 info 14796 --- [ main] com.netflix.discovery.discoveryclient : the response status is 200 2019-06-15 13:08:06.882 info 14796 --- [ main] com.netflix.discovery.discoveryclient : starting heartbeat executor: renew interval is: 30 2019-06-15 13:08:06.886 info 14796 --- [ main] c.n.discovery.instanceinforeplicator : instanceinforeplicator ondemand update allowed rate per min is 4 2019-06-15 13:08:06.891 info 14796 --- [ main] com.netflix.discovery.discoveryclient : discovery client initialized at timestamp 1560575286889 with initial instances count: 2 2019-06-15 13:08:06.894 info 14796 --- [ main] o.s.c.n.e.s.eurekaserviceregistry : registering application service-ribbon with eureka with status up 2019-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: 204 2019-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 8764 2019-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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: session 加入mysql库的方法