Eureka

1 介绍

  1. Spring-Cloud Eureka介绍

    • Spring-Cloud Eureka是Spring Cloud集合中一个组件,它是对Eureka的集成,用于服务注册和发现。Eureka是Netflix中的一个开源框架。它和Zookeeper、Consul一样,都是用于服务注册管理的,同样,Spring-Cloud还集成了Zookeeper和Consul。
    • 在项目中使用Spring Cloud Eureka的原因是它可以利用Spring Cloud Netflix中其他的组件,如zuul等,因为Eureka是属于Netflix的。
  2. Eureka

    Eureka由多个instance(服务实例)组成,这些服务实例可以分为两种:Eureka ServerEureka client再分为Service Provider和Service Consumer(下面三角图示)

    • Eureka Server提供服务注册和发现
    • Service Provider服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
    • Service Consumer服务消费方,从Eureka获取注册服务列表,从而能够消费服务

1.1 Eureka与Zookeeper比较

  • P:Partition tolerance,网络分区容错。****类似多机房部署,保证服务稳定性
  • A:Availability,可用性
  • C:Consistency,一致性

CAP定理:CAP三个属性对于分布式系统不能同时做到。如AP/CP/AC。再来看Eureka和Zookeeper区别:
(1)Zookeeper是CP,分布式协同服务,突出一致性。对Zookeeper的每次请求都能得到一致的数据结果,但是无法保证每次访问服务可用性。如请求到来时,zookeeper正在做leader选举,此时不能提供服务,即不满足A可用性
(2)Eureka是AP,高可用与可伸缩的Service发现服务,突出可用性。相对于Zookeeper而言,可能返回数据没有一致性,但是保证能够返回数据,服务是可用的。


2 部署Eureka Server

  • 1. pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        <version>2.2.1.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- 开启自动热部署Devtools -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

</dependencies>
  • 2. 写yaml
server:
  port: 7001

#与7002形成互相注册,相互守望
eureka:
  instance:
    # eureka服务端的实例名称
    hostname: eureka7001.com   #eureka服务端的实例名称【在主机host文件中修改映射地址】
  client:
    # false表示不向注册的中心注册自己
    register-with-eureka: false
    # false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #集群指向其他eureka
      defaultZone: http://eureka7002.com:7002/eureka/
      #单机就是指向自己
#      defaultZone: http://eureka7001.com:7001/eureka/
#
#  server:
#    #关闭自我保护机制,保证不可用服务被及时剔除
#    enable-self-preservation: false
#    eviction-interval-timer-in-ms: 2000
  • 3. 启动类
@SpringBootApplication
//@EnableEurekaServer表明我是**注册中心,管理配置、注册**
@EnableEurekaServer
public class EurekaMain7001 {

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

3 部署Eureka Client

  1. Eureka Client包括两个服务模块:Sevice Provider(服务提供方)和Serivce Consumer(服务消费方)
  2. Eureka Client和Eureka Server目录类似,不同点在于:
    • 启动类,使用@EnableDiscoveryClient标识该服务为Eureka Client
    • 配置文件,需要指定Eureka Server地址和当前服务注册时的名称

3.1 部署Service Provider

  • 1. pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        <version>2.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
    <!-- mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- jdbc -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- 开启自动热部署Devtools -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

</dependencies>
  • 2. 写yaml
#服务端口号
server:
  port: 8001

#服务名称
spring:
  application:
    name: cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource   # 当前数据源操作类型
    driver-class-name: com.mysql.jdbc.Driver       # mysql驱动包
    url: jdbc:mysql://localhost:3306/db2019?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: xzh

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包
eureka:
  client:
    #表示是否将自己注册进EurekaServer,默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      #单机版
      defaultZone: http://localhost:7001/eureka
      #集群版
#      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    instance-id: payment8001
    prefer-ip-address: true     #访问路径可以显示IP地址
    #心跳检测与续约时间
    #开发时设置小些,保证服务关闭后注册中心能及时剔除服务
    #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    lease-renewal-interval-in-seconds: 1
    #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
    lease-expiration-duration-in-seconds: 2

  • 3. 启动类
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}

3.2 部署Service Customer

  • 1. pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        <version>2.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- 开启自动热部署Devtools -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

</dependencies>

  • 2. 写yaml
server:
  port: 80

spring:
  application:
    name: cloud-order-service

eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
#      defaultZone: http://localhost:7001/eureka
      #集群版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

  • 3. 启动类
@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}

4 自我保护机制

保护模式,是Eureka提供的一个特性,在默认的情况下,这个属性是打开的,而且也建议线上都使用这个特性。

如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,此时会触发Eureka Server进入保护模式,进入自我保护模式后,将会保护服务注册表中的信息,不再删除服务注册表中的数据。

  • 相关设置

    对于自我保护模式属性,建议都是使用默认的配置,不需要要设置这些属性。
    (1)Eureka Server端
    默认情况下自我保护机制是打开的,线上建议都是打开的,即不需要设置。如果在测试环境需要设置为关闭,可以通过如下配置:

# 设为false,关闭自我保护。**默认是打开的。**
eureka.server.enable-self-preservation=false

设置清零失效服务的间隔时间,但是不建议更改

# 清理间隔(单位毫秒,默认是60*1000)
eureka.server.eviction-interval-timer-in-ms=4000

这个“eureka.server.eviction-interval-timer-in-ms”时间,是Eureka Server执行清理无效服务的时间间隔,执行新清理任务时,如果下面判断生效,则清除服务。

当前时间 - 上次心跳时间 > lease-expiration-duration-in-seconds

其中,lease-expiration-duration-in-seconds 属性在客户端进行配置

这里一个规范就是:服务端的“eureka.server.eviction-interval-timer-in-ms”  值  要比 客户端配置 “lease-expiration-duration-in-seconds ”的时间短。

(2) Eureka Client端

开启健康检查,默认是开启的,如下

eureka.client.healthcheck.enabled=true

心跳相关的设置

**单位是秒,默认30秒。此客户端发送心跳的频率**
eureka.instance.lease-renewal-interval-in-seconds=30

**单位是秒,默认90秒,表示eureka server在收到此client上次心跳之后,间隔多久没有收到,就摘除此服务。**
eureka.instance.lease-expiration-duration-in-seconds=10

单位是秒,默认30秒。此客户端发送心跳的频率

eureka.instance.lease-renewal-interval-in-seconds=30

单位是秒,默认90秒,表示eureka server在收到此client上次心跳之后,间隔多久没有收到,就摘除此服务。

eureka.instance.lease-expiration-duration-in-seconds=10
posted @ 2022-01-24 10:30  ArosyCat  阅读(336)  评论(0编辑  收藏  举报