详解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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- SpringMVC【开发Controller】详解
- 巧用外部表备份历史数据(r5笔记第62天)
- Github 项目推荐 | 最小化类 AlphaGo Zero 引擎 —— Nochi
- 半自动化运维之快速连接到指定环境(一) (r5笔记第61天)
- Spring【DAO模块】知识要点
- 浅谈exp/imp(上) (r5笔记第81天)
- Java高并发秒杀系统【观后总结】
- 【专业技术】引擎算法探究
- 阅读SSM项目之scm
- 阅读SSH项目之ERP
- Hybris商品图片导入与压缩有关的配置
- 一条sql语句的建议调优分析(r5笔记第73天)
- O API - REST APIs的替代品
- 【专业技术】从4行代码看右值引用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PAT (Basic Level) Practice (中文)1045 快速排序 (25 分)
- PAT (Advanced Level) Practice 1028 List Sorting (25分)
- CNS图表复现06—根据CellMarker网站进行人工校验免疫细胞亚群
- 【Java】03 流程控制语句
- Artwork (Gym - 102346A)【DFS、连通块】
- PAT (Basic Level) Practice (中文)1046 划拳 (15 分)
- PAT (Advanced Level) Practice 1030 Travel Plan (30分)
- PAT (Basic Level) Practice (中文)1050 螺旋矩阵 (25 分)
- PAT (Advanced Level) Practice 1031 Hello World for U (20分)
- PAT (Basic Level) Practice (中文)1051 复数乘法 (15 分)
- 【Java】06 面向对象基本特征
- PAT (Basic Level) Practice (中文)1054 求平均值 (20 分)
- zookeeper集群的搭建
- 【Java】07 常见 API
- 【Java】04 数组