SpringCloud入门(一):服务的注册与发现Eureka(Greenwich.SR2)

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

1.eureka简介

在这里插入图片描述
Eureka包含两个组件:Eureka server和Eureka client。

调用关系说明

  1. 服务提供者在服务启动时,向注册中心注册自己提供的服务。
  2. 服务消费者在服务启动时,向注册中心订阅自己所需的服务。
  3. 注册中心返回服务提供者的地址给消费者。
  4. 服务消费者从提供者的地址中调用消费。

注意:下面的服务端是指注册中心,客户端是指服务提供者和服务消费者

Eureka Server: 提供服务注册服务,每个节点启动后,会在Eureka Server中进行注册,包括主机、端口号、服务版本号、通讯协议等。Eureka Server中的服务注册表将会存储所有可用服务节点的信息,服务节点信息可在界面中直观的看到。

Eureka服务端支持集群模式部署,首位相连形成一个闭环即可,集群中的不同服务注册中心通过异步模式相互复制各自的状态,这也意味着在给定的时间点每个实例在所有服务注册中心的状态存在不一致的现象。

Eureka Client: 主要处理服务的注册和发现。客户端服务通过注册和参数配置的方式,嵌入在客户端应用程序的代码中。在应用程序启动时,Eureka客户端向服务注册中心注册自身提供的服务,并周期性的发送心跳来更新它的租约,同时,也可以从服务端查询当前注册的服务信息把它们缓存到本地并周期性的刷新服务状态。

服务调用
服务消费者在获取服务清单后,通过服务名可以获取具体提供服务的实例名和该实例的元数据信息。因为有这些服务实例的详细信息,所以客户端可以根据自己的需要决定具体调用哪个实例,在Ribbon中会默认采用轮询的方式进行调用,从而实现客户端的负载均衡。

2.服务注册中心搭建

相关博客都是采用Module的方式实现
创建springcloud工程,然后创建microservice-eureka子模块

引入相关依赖

父级pom文件,springcloud的相关依赖都在父级中类引用,子级则不用再单独引用(java的继承关系),不清楚的可以谷歌maven

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.zfw.springcloud</groupId>
    <artifactId>springcloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modules>
        <module>microservice-register</module>
    </modules>
    <!--<packaging>pom</packaging>-->

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.12</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

子级pom

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

<!--已经废弃,不推荐使用-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
<!--<dependency>-->
    <!--<groupId>org.springframework.cloud</groupId>-->
    <!--<artifactId>spring-cloud-starter-eureka-server</artifactId>-->
    <!--<version>1.4.7.RELEASE</version>-->
<!--</dependency>-->

启动类
@EnableEurekaServer声明一个注册中心

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }

}

yml配置

spring:
  application:
    name: eurekaServer

# eureka 默认端口为:8761
server:
  port: 8761

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:${server.port}/eureka/
    #是否注册到eureka(eureka本身是不需要再注册到自己的)单机版关闭注册,本身就是注册中心
    register-with-eureka: false
    #是否从注册中心获取注册信息
    fetch-registry: false
  instance:
    #服务失效时间,Eureka多长时间没收到服务的renew操作,就剔除该服务,默认90秒
    lease-expiration-duration-in-seconds: 15
  server:
    # 自我保护模式(缺省为打开)线上建议打开,测试环境关闭就好
    enable-self-preservation: false
    #eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
    # 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
    eviction-interval-timer-in-ms: 5000

3.高可用的注册中心

在现在的互联网时代,一个系统可能由成千上万个服务组成,试想一下,所有的服务都往一个服务注册中心注册,那么注册中心的负载是相当高的,随时可能宕机,在线上是不允许的。就需要用到高可用的注册中心了。
Eureka Server在设计的时候就考虑了高可用设计,在Eureka服务治理设计中,所有节点既是服务的提供方,也是服务的消费方,服务注册中心也不例外。

Eureka的高可用实际上就是将自己作为服务向其它服务注册中心注册,这样就可以形成一组互相注册的服务注册中心,以实现服务清单的同步,达到高可用的效果。
Eureka Server的同步遵循着一个非常简单的原则:只要有一条边将节点连接,就可以进行信息传播与同步。可以采用两两注册的方式实现集群中节点完全对等的效果,实现最高可用性集群,任何一台注册中心故障都不会影响服务的注册与发现。

我们新建3个配置文件,来搭建3个服务注册中心。
application-eureka1.yml、application-eureka2.yml、application-eureka3.yml
首先修改hosts文件,win的hosts文件目录 C:\Windows\System32\drivers\etc ,因为是受保护的,建议使用notepad++编辑,直接切换到管理员保存即可
在这里插入图片描述
application-eureka1.yml

spring:
  application:
    name: eurekaServer

server:
  port: 8761

eureka:
  client:
    service-url:
      #eureka1 eureka2 对应hosts
      defaultZone: http://eureka2:8762/eureka/,http://eureka3:8763/eureka/
    #单机版为false,关闭自我注册功能,集群需要打开自我注册,所有注册中心相互注册
    register-with-eureka: true
    #默认为true,会从注册中心获取注册信息缓存到本地,以后只会增量获取,可以搭配disable-delta : false来强制每次全部获取
    fetch-registry: true
    #默认开启增量获取更新注册表信息,false则每次会全部获取
    disable-delta: true
  instance:
    hostname: eureka1
    #服务失效时间,Eureka多长时间没收到服务的renew操作,就剔除该服务,默认90秒
    lease-expiration-duration-in-seconds: 15
  server:
    #关闭自我保护机制,缺省为打开(将失效的服务实例保护起来,不予剔除)
    enable-self-preservation: false
    #eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
    # 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
    eviction-interval-timer-in-ms: 10000

application-eureka2.yml

spring:
  application:
    name: eurekaServer

server:
  port: 8762

eureka:
  client:
    service-url:
      #eureka1 eureka3 对应hosts
      defaultZone: http://eureka1:8761/eureka/,http://eureka3:8763/eureka/
    #单机版为false,关闭自我注册功能,集群需要打开自我注册,所有注册中心相互注册
    register-with-eureka: true
    #默认为true,会从注册中心获取注册信息缓存到本地,以后只会增量获取,可以搭配disable-delta : false来强制每次全部获取
    fetch-registry: true
    #默认开启增量获取更新注册表信息,false则每次会全部获取
    disable-delta: true
  instance:
    hostname: eureka2
    #服务失效时间,Eureka多长时间没收到服务的renew操作,就剔除该服务,默认90秒
    lease-expiration-duration-in-seconds: 15
  server:
    #关闭自我保护机制,缺省为打开(将失效的服务实例保护起来,不予剔除)
    enable-self-preservation: false
    #eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
    # 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
    eviction-interval-timer-in-ms: 10000

application-eureka3.yml

spring:
  application:
    name: eurekaServer

server:
  port: 8763

eureka:
  client:
    service-url:
      #eureka1 eureka2 对应hosts
      defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/
    #单机版为false,关闭自我注册功能,集群需要打开自我注册,所有注册中心相互注册
    register-with-eureka: true
    #默认为true,会从注册中心获取注册信息缓存到本地,以后只会增量获取,可以搭配disable-delta : false来强制每次全部获取
    fetch-registry: true
    #默认开启增量获取更新注册表信息,false则每次会全部获取
    disable-delta: true
  instance:
    hostname: eureka3
    #服务失效时间,Eureka多长时间没收到服务的renew操作,就剔除该服务,默认90秒
    lease-expiration-duration-in-seconds: 15
  server:
    #关闭自我保护机制,缺省为打开(将失效的服务实例保护起来,不予剔除)
    enable-self-preservation: false
    #eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
    # 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
    eviction-interval-timer-in-ms: 10000

我们来启动3个配置文件,启动的时候会有错误日志,暂且不管,等3个服务都起来就ok了,原因就不用多说了吧。
好了,我们来通过浏览器来查看我们注册中心,效果如下
在这里插入图片描述
如果你的各个节点在不可用中,可以按照以下来检查你的配置

  1. spring.application.name 名称是否一致,可不写,否则必须要一致
  2. eureka.client.serviceUrl.defualtZone配置的地址,不能使用localhost,要是域名,hosts中配置的
  3. register-with-eureka和fetch-register是否为true,不配置也行
  4. 配置eureka.instance.hostname(各节点在同一机器下)
  5. 如果还不能,奉上网友的一种方法,未测试过,去掉eureka.instance.prefer-ip-address:true或者改为false

4.客户端

启动类
@EnableDiscoveryClient或者@EnableEurekaClient
1,@EnableDiscoveryClient注解是基于spring-cloud-commons依赖,并且在classpath中实现;
2,@EnableEurekaClient注解是基于spring-cloud-netflix依赖,只能为eureka作用;
如果你的classpath中添加了eureka,则它们的作用是一样的。

@EnableEurekaClient
@SpringBootApplication
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

yml配置

spring:
  application:
    name: provider-service

server:
  port: 8764

eureka:
  client:
    service-url:
#      defaultZone: http://eureka1:8761/eureka/
      defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/,http://eureka3:8763/eureka/
  instance:
    #10秒没有续约,Server会认为改服务宕机,会从服务列表剔除
    lease-expiration-duration-in-seconds: 10
    #服务续约时间单位:秒,默认30秒
    lease-renewal-interval-in-seconds: 5

defaultZone往每一个服务注册中心注册,避免只注册一个服务中心的情况下,刚好注册的注册中心挂掉,则这个服务就不会被其它服务发现。

5.eureka配置项解读

在注册服务之后,服务提供者会维护一个心跳来持续告诉Eureka Server,我还在持续提供服务。否则Eureka Server的剔除任务会将该实例从服务列表中剔除,我们称之为服务续约。
下面是服务续约的两个重要属性

eureka.instance.lease-expiration-duration-in-seconds
leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。
默认为90秒
如果该值太大,则很可能将流量转发过去的时候,该instance已经不存活了。
如果该值设置太小了,则instance则很可能因为临时的网络抖动而被摘除掉。
该值至少应该大于leaseRenewalIntervalInSeconds

eureka.instance.lease-renewal-interval-in-seconds
leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance。除此之外,如果该instance实现了HealthCheckCallback,并决定让自己unavailable的话,则该instance也不会接收到流量。
默认30秒

eureka.client.registry-fetch-interval-seconds
表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒

eureka.server.enable-self-preservation
是否开启自我保护模式,默认为true。
默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。
Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

eureka.server.eviction-interval-timer-in-ms
eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒

发布了34 篇原创文章 · 获赞 5 · 访问量 1718

猜你喜欢

转载自blog.csdn.net/zhengliangs/article/details/102852551