欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-02 10:22:48
一,问题 采取eureka集群、客户端通过ribbon调用服务,ribbon端报下列异常 java.net.unknownhostexception: serv...

一,问题

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

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

分析原理:我的客户端服务“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

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

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

五,附件: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>

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