当前位置: 移动技术网 > IT编程>开发语言>Java > 详解SpringCloud Ribbon 负载均衡通过服务器名无法连接的神坑

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

一,问题

采取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>

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网