springcloud2 (三) 服务治理Eureka及其实现原理

代码地址:https://gitlab.com/showkawa/architect/tree/master/microservice/eurakegit

基于springcloud2分析eurake知识点分三部分:eurake高可用集群搭建, eurake的自我保护机制 ,eurake的原理分析web

1.eurake高可用集群搭建

高可用注册中心

在微服务中,注册中心很是核心,能够实现服务治理,若是一旦注册出现故障的时候,可能会致使整个微服务没法访问,在这时候就须要对注册中心实现高可用集群模式。spring

Eureka高可用原理

默认状况下Eureka是让服务注册中心,不注册本身缓存

###由于该应用为注册中心,不会注册本身

    register-with-eureka: true

###不须要去注册中心上检索服务

    fetch-registry: true


Eureka高可用实际上将本身做为服务向其余服务注册中心注册本身,这样就能够造成一组相互注册的服务注册中心,从而实现服务清单的互相同步,达到高可用效果。服务器

Eureka集群环境搭建

Eureka 1 配置

###服务端口号
server:
  port: 9100
###eureka 基本信息配置
spring:
  application:
    name: brian-eureka-server
eureka:
  instance:
    ###注册到eurake ip地址
    hostname: 127.0.0.1
  client:
    serviceUrl:
      defaultZone: http://127.0.0.1:9200/eureka/
    ###由于本身是为注册中心,不须要本身注册本身
    register-with-eureka: true
    ###由于本身是为注册中心,不须要检索服务
    fetch-registry: true

Eureka 2 配置

###服务端口号
server:
  port: 9200
###eureka 基本信息配置
spring:
  application:
    name: brian-eureka-server
eureka:
  instance:
    ###注册到eurekaip地址
    hostname: 127.0.0.1
  client:
    serviceUrl:
      defaultZone: http://127.0.0.1:9100/eureka/
    ###由于本身是为注册中心,不须要本身注册本身
    register-with-eureka: true
    ###由于本身是为注册中心,不须要检索服务
    fetch-registry: true

客户端集成Eureka集群配置

server:
  port: 8012
###服务别名----服务注册到注册中心名称
spring:
  application:
    name: brian-member-server
eureka:
  client:
    service-url:
      ##### 将会员服务注册到eureka服务地址
      defaultZone: http://localhost:9200/eureka,http://localhost:9100/eureka
    ### 须要将个人服务注册到eureka上
    register-with-eureka: true
    ####须要检索服务
    fetch-registry: true

Maven配置

 服务端配置
 <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-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</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>

    <!-- 注意: 这里必需要添加, 否者各类依赖有问题 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
客户端配置
 <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-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

测试eurake集群

开启5个服务,注册中心2个 EurakeServerApplication 01和02 ,会员member服务2个, 订单order服务1个网络

 

查看注册中心端口 9100,此时上面只显示有9200eurake的注册信息,说明如今该9100端口的注册中心是备机app

查看注册中心端口 9200,此时上面只显示有全度启动的服务的注册信息jvm

此时使用订单服务order采用RestTemplate方式调用会员服务member, 能够看到会轮询调用到两个会员服务8011和8012端口的服务maven

 如今咱们假设注册中心9200的服务和会员服务8012服务同时不可用spring-boot

如今发现以前注册的服务信息从9200的注册中心转移到了9100注册中心上去了

 

原来的order仍然可用,只是如今的轮询机制调用的是8011这个端口的会员member服务

因此说eurake在高可用方面仍是不错的,经过简单的配置就能够实现一个高可用的集群

2.eurake的自我保护机制 

Eureka详解

服务消费者模式

获取服务

 消费者启动的时候,使用服务别名,会发送一个rest请求到服务注册中心获取对应的服务信息,让后会缓存到本地jvm客户端中,同时客户端每隔30秒从服务器上更新一次。

能够经过 registry-fetch-intevall-seconds=30参数进行修以经过eureka.client .registry-fetch-intevall-seconds该参数默认值为30, 单位为秒。

服务下线

    在系统运行过程当中必然会面临关闭或重启服务的某个实例的状况,在服务关闭期有咱们天然不但愿客户端会继续调用关闭了的实例。因此在客户端程序中,当服务实例过正常的关闭操做时,它会触发一个服务下线的REST请求给Eureka Server, 告诉服务日中心:“我要下线了”。服务端在接收到请求以后,将该服务状态置为下线(DOWN),井该下线事件传播出去。

服务注册模式

 失效剔除

 有些时候,咱们的服务实例并不必定会正常下线,可能因为内存溢出、网络故障气因使得服务不能正常工做,而服务注册中心并未收到“服务下线”的请求。为了从服务表中将这些没法提供服务的实例剔除,Eureka Server 在启动的时候会建立一个定时任务默认每隔一一段时间(默认为60秒)将当前清单中超时(默认为90秒)没有续约的服务除出去

 自我保护

  当咱们在本地调试基于Eureka的程序时,基本上都会碰到这样-一个问题, 在服务主中心的信息面板中出现相似下面的红色警告信息( )

 

      EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY 'RERENENALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIREDTO BE SAFE.

 

实际上,该警告就是触发了Eureka Server的自我保护机制。以前咱们介绍过,服务注册到Eureka Server以后,会维护个心跳链接, 告诉Eureka Server本身还活着。Eureka Server在运行期间,会统计心跳失败的比例在15分钟以内是否低于85%若是出现低于的状况单机调试的时候很容易知足,实际在生产环境上一般是因为网络不稳定致使,Eureka Server会将当前的实例注册信息保护起来,让这些实例不会过时,尽量保护这些注册信-息。可是,在这段保护期间内实例若出现问题,那么客户端很容易拿到实际已经不存服务实例,会出现调用失败的状况,因此客户端必需要有容错机制,好比可使用请使用重试、断路器等机制。

因为本地调试很容易触发注册中心的保护机制,这会使得注册中心维护的服务不会特别准确。因此,咱们在本地进行开发的时候,可使用eureka.server.enablp-self-preservation=false参数来关闭保护机制,以确保注册中心能够将不可用的例正确剔除。

关闭服务保护

Eureka服务器端配置 这里以9100端口的注册中心为例,添加如下核心配置
  server:
    # 开发测试时关闭自我保护机制,保证不可用服务及时踢出
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000

注意追加的内容是在根节点eureka下面追加的配置

Eureka客户端配置 这里以8011端口的会员服务为例,添加如下核心配置
  # 心跳检测检测与续约时间
  # 测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
  instance:
    ###Eureka客户端向服务端发送心跳的时间间隔,单位为秒(客户端告诉服务端本身会按照该规则)
    lease-renewal-interval-in-seconds: 1
    ####Eureka服务端在收到最后一次心跳以后等待的时间上限,单位为秒,超过则剔除(客户端告诉服务端按照此规则等待本身)
    lease-expiration-duration-in-seconds: 2

这里跟上面的配置同样也是基于eureka做为根节点追加的

 此处就不一一截图了,感兴趣的能够本身下载代码测试

 3.eurake的原理分析

1.当启动eurake客户端应用,好比上面说到的会员服务member,会把当前服务好比服务地址和端口以别名的注册到注册中心

2.当服务消费者好比上面说到的order订单服务,在接口调用的时候,使用服务别名也就是service id去注册中心获取实际的rpc远程调用地址

3. 服务消费者在获取到实际的rpc远程调用地址后,在本地使用HttpClient技术调用远程接口

流程图以下: