spring cloud组件之 eureka搭建、集群、心跳

相关阅读:
SpringBoot2.X快速构建和配置
微服务入门 spring cloud环境搭建

1.eureka是什么?

eureka是Netflix的子模块之一,也是一个核心的模块,eureka里有2个组件,一个是EurekaServer(一个独立的项目) 这个是用于定位服务以实现中间层服务器的负载平衡和故障转移,另一个便是EurekaClient(我们的微服务) 它是用于与Server交互的,可以使得交互变得非常简单:只需要通过服务标识符即可拿到服务。

2. 与spring-cloud的关系:

Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(可以对比Zookeeper)。
Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。
而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。SpringCloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。

3. 角色关系图

在这里插入图片描述

4 如何使用

4.1 添加依赖

客户端:

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

服务端:

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

添加相关依赖

当然不管是服务端还是客户端都需要添加springCloud的支持

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

4.2 服务端配置

服务端配置信息:yml或者properties文件都可以

server:
  port: 3000
eureka:
  server:
    enable-self-preservation: false  #关闭自我保护机制
    eviction-interval-timer-in-ms: 4000 #设置清理间隔(单位:毫秒 默认是60*1000)
  instance:
    hostname: localhost


  client:
    registerWithEureka: false #不把自己作为一个客户端注册到自己身上
    fetchRegistry: false  #不需要从服务端获取注册信息(因为在这里自己就是服务端,而且已经禁用自己注册了)
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka

自我保护机制 这里展开一下,
定义:
当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
简单理解:当一个服务和Eureka失联后,Eureka认为这个服务的问题,当大部分服务都失联(网络中断)这个时候Eureka不再认为是服务的问题,就怀疑人生,感觉是自己出现了问题,不再清除,跟新任何服务注册列表中的数据
意义:
自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定

在这里插入图片描述
出现这个页面就证明搭建成功, 这个警告是因为自我保护机制关闭的原因,先不关了

4.3 客户端配置

server:
  port: 8082
eureka:
  client:
    serviceUrl:
        defaultZone: http://localhost:3000/eureka  #eureka服务端提供的注册地址 参考服务端配置的这个路径
  instance:
    instance-id: user-1 #此实例注册到eureka服务端的唯一的实例ID
    prefer-ip-address: true #是否显示IP地址
    leaseRenewalIntervalInSeconds: 10 #eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30(与下面配置的单位都是秒)
    leaseExpirationDurationInSeconds: 30 #Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒

spring:
  application:
    name: client-user #此实例注册到eureka服务端的name

然后在客户端的spring-boot启动项目上 加入注解:@EnableEurekaClient 就可以启动项目了 这里就不截图了我们直接来看效果图:
在这里插入图片描述
这里我们能看见 名字叫server-power的(图中将其大写了) id为 power-0的服务 注册到我们的Eureka上面来了 至此,一个简单的eureka已经搭建好了。

在这里插入图片描述

eviction-interval-timer-in-ms: 4000 #设置清理间隔(单位:毫秒 默认是60*1000)
leaseRenewalIntervalInSeconds: 10 #eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒 (与下面配置的单位都是秒)
leaseExpirationDurationInSeconds: 30 #Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒

每10秒给我发一个心跳,如果没发就等待30秒,不然定期(4000ms)进行清理,这就好比一个美女有很多追求者,需要管理这些追求者,美女怎么知道这些追求者是否移心别恋了,需要定期给美女放电,如果超过约定的时间,最多等待多久,这里主要考虑,网络抖动,而不是服务器自己真的挂了,如果说是因为其他的事情导致的放电失败,我可以最多宽容你多久,把那些超过等待时间的定期进行清理

5.eureka集群

为什么我们需要配置eureka集群?
所以的服务都注册到eurekaserver,万一eureka自己宕机了怎么办,不是整个系统都瘫痪了,这种不符合高可用的原来所以需要eureka进行集群.

5.1eureka集群原理

服务启动后向Eureka注册,Eureka Server会将注册信息向其他Eureka Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。

这里eureka和zookeeper的集群还有些不太一样,zookeeper是分lender和flower的eureka不区分这些,也就是说都是全部平等的,
spring cloud组件之 eureka搭建、集群、心跳_第1张图片

5.2 eureka集群配置

Eureka Server会将注册信息向其他Eureka Server进行同步 那么我们得声明有哪些server呢?
这里 假设我们有3个Eureka Server 如图:
spring cloud组件之 eureka搭建、集群、心跳_第2张图片

5.2.1 3000配置

server:
  port: 3000
eureka:
  server:
    enable-self-preservation: false  #关闭自我保护机制
    eviction-interval-timer-in-ms: 4000 #设置清理间隔(单位:毫秒 默认是60*1000)
  instance:
    hostname: localhost
    ip-address: 127.0.0.1


  client:
    registerWithEureka: false #不把自己作为一个客户端注册到自己身上
    fetchRegistry: false  #不需要从服务端获取注册信息(因为在这里自己就是服务端,而且已经禁用自己注册了)
    serviceUrl:
      defaultZone: http://127.0.0.1:3001/eureka,http://127.0.0.1:3002/eureka

原来我是没有配置ip-address

5.2.2 3001配置

server:
  port: 3001
eureka:
  server:
    enable-self-preservation: false  #关闭自我保护机制
    eviction-interval-timer-in-ms: 4000 #设置清理间隔(单位:毫秒 默认是60*1000)
  instance:
    hostname: localhost
    ip-address: 127.0.0.1


  client:
    registerWithEureka: false #不把自己作为一个客户端注册到自己身上
    fetchRegistry: false  #不需要从服务端获取注册信息(因为在这里自己就是服务端,而且已经禁用自己注册了)
    serviceUrl:
      defaultZone: http://127.0.0.1:3000/eureka,http://127.0.0.1:3002/eureka

5.2.3 3002配置

server:
  port: 3002
eureka:
  server:
    enable-self-preservation: false  #关闭自我保护机制
    eviction-interval-timer-in-ms: 4000 #设置清理间隔(单位:毫秒 默认是60*1000)
  instance:
    hostname: localhost
    ip-address: 127.0.0.1


  client:
    registerWithEureka: false #不把自己作为一个客户端注册到自己身上
    fetchRegistry: false  #不需要从服务端获取注册信息(因为在这里自己就是服务端,而且已经禁用自己注册了)
    serviceUrl:
      defaultZone: http://127.0.0.1:3001/eureka,http://127.0.0.1:3000/eureka

没有配置ip-address时eureka不进行信息同步,原因解释如下:

由于我们的产品需要提供给不同的客户,不同客户对应主机有不同的要求,有的不会让我们拥有更改hostname的权限。所以我们选用的第二种方法,使用ipAddress来注册。不过需要在网易的博客上面多加一条,指定该Eureka Server的ip-address

也可以使用
这里 方便理解集群 我们做了一个域名的映射(条件不是特别支持我使用三台笔记本来测试。。。) 至于域名怎么映射的话 这里简单提一下吧 修改你的hosts文件(win10的目录在C:\Windows\System32\drivers\etc 其他系统的话自行百度一下把)附上我的hosts文件:
127.0.0.1 eureka3000.com
127.0.0.1 eureka3001.com
127.0.0.1 eureka3002.com

不过这个地方遇到这么一个坑,也让我可以看到,Eureka集群起来之后再启动UserServe服务器发现只注册到3002上面,其他2个并没有注册
虽然UserServer配置了3个链接,也就是说UserServer在注册中心注册成功后不会再注册到第二个上面,至于他们各自的数据都是再集群中进行同步的

我们回到主题, 我们发现 集群配置与单体不同的点在于 原来是把服务注册到自己身上,而现在是注册到其它服务身上
至于为什么不注册自己了呢?,回到最上面我们说过,eureka的server会把自己的注册信息与其他的server同步,所以这里我们不需要注册到自己身上,因为另外两台服务器会配置本台服务器。(这里可能有点绕,可以参考一下刚刚那张集群环境的图,或者自己动手配置一下,另外两台eureka的配置与这个是差不多的,就不发出来了,只要注意是注册到其他的服务上面就好了)
当三台eureka配置好之后,全部启动一下就可以看见效果了:

spring cloud组件之 eureka搭建、集群、心跳_第3张图片
无论查询3000,3001,3002都可以看到user服务

5.3 客户端配置

 defaultZone: http://localhost:3000/eureka,http://localhost:3001/eureka,http://localhost:3002/eureka

我们这里只截取了要改动的那一部分。 就是 原来是注册到那一个地址上面,现在是要写三个eureka注册地址,但是不是代表他会注册三次,因为我们eureka server的注册信息是同步的,这里只需要注册一次就可以了,但是为什么要写三个地址呢。因为这样就可以做到高可用的配置:打个比方有3台服务器。但是突然宕机了一台, 但是其他2台还健在,依然可以注册我们的服务,换句话来讲, 只要有一台服务还建在,那么就可以注册服务,这里 需要理解一下。

无论是客户端这种配置还是服务器双向注册都是为了高可用,这种配置即便Eureka3个挂掉2台也是可以使用的

6. CAP理论

spring cloud组件之 eureka搭建、集群、心跳_第4张图片

1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标。
Consistency —一致性
Availability —可用性
Partition tolerance —分区容错性
他们第一个字母分别是C,A,P
Eric Brewer 说,这三个指标不可能同时做到。这个结论就叫做 CAP 定理。
1. Partition tolerance
中文叫做"分区容错"。
大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容错的意思是,区间通信可能失败。比如,一台服务器放在本地,另一台服务器放在外地(可能是外省,甚至是外国),这就是两个区,它们之间可能无法通信。

spring cloud组件之 eureka搭建、集群、心跳_第5张图片
上图中,S1 和 S2 是两台跨区的服务器。S1 向 S2 发送一条消息,S2 可能无法收到。系统设计的时候,必须考虑到这种情况。
一般来说,分区容错无法避免,因此可以认为 CAP 的 P 总是成立。CAP 定理告诉我们,剩下的 C 和 A 无法同时做到。

Consistency
Consistency 中文叫做"一致性"。意思是,写操作之后的读操作,必须返回该值。举例来说,某条记录是 v0,用户向 S1 发起一个写操作,将其改为 v1。

spring cloud组件之 eureka搭建、集群、心跳_第6张图片
接下来用户读操作就会得到v1。这就叫一致性。

问题是,用户有可能会向S2发起读取操作,由于S2的值没有发生变化,因此返回的是v0,所以S1和S2的读操作不一致,这就不满足一致性了
spring cloud组件之 eureka搭建、集群、心跳_第7张图片
为了让S2的返回值与S1一致,所以我们需要在往S1执行写操作的时候,让S1给S2也发送一条消息,要求S2也变成v1

Availability
Availability 中文叫做"可用性",意思是只要收到用户的请求,服务器就必须给出回应。
用户可以选择向 S1 或 S2 发起读操作。不管是哪台服务器,只要收到请求,就必须告诉用户,到底是 v0 还是 v1,否则就不满足可用性。

简单一句话概括: 就是对S1写操作的时候对S2是否进行锁操作,如果锁就不能进行满足可用性,如果不锁就不能满足一致性

Consistency 和 Availability 的矛盾
一致性和可用性,为什么不可能同时成立?答案很简单,因为可能通信失败(即出现分区容错)。
如果保证 S2 的一致性,那么 S1 必须在写操作时,锁定 S2 的读操作和写操作。只有数据同步后,才能重新开放读写。锁定期间,S2 不能读写,没有可用性不。
如果保证 S2 的可用性,

7 eureka对比Zookeeper:

Zookeeper在设计的时候遵循的是CP原则,即一致性,Zookeeper会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时剩余节点会重新进行leader选举,问题在于,选举leader的时间太长:30~120s,且选举期间整个Zookeeper集群是不可用的,这就导致在选举期间注册服务处于瘫痪状态,在云部署的环境下,因网络环境使Zookeeper集群失去master节点是较大概率发生的事情,虽然服务能够最终恢复,但是漫长的选举时间导致长期的服务注册不可用是不能容忍的。
Eureka在设计的时候遵循的是AP原则,即可用性。Eureka各个节点(服务)是平等的, 没有主从之分,几个节点down掉不会影响正常工作,剩余的节点(服务) 依然可以提供注册与查询服务,而Eureka的客户端在向某个Eureka注册或发现连接失败,则会自动切换到其他节点,也就是说,只要有一台Eureka还在,就能注册可用(保证可用性), 只不过查询到的信息不是最新的(不保证强一致),除此之外,Eureka还有自我保护机制,如果在15分钟内超过85%节点都没有正常心跳,那么eureka就认为客户端与注册中心出现了网络故障,此时会出现一下情况:
1: Eureka 不再从注册列表中移除因为长时间没有收到心跳而过期的服务。
2:Eureka 仍然能够接收新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点可用)
3: 当网络稳定后,当前实例新的注册信息会被同步到其它节点中

结合我们平时生活中遇到的情况想想是ap原则还是cp原则:

比如:1双十一大家都在抢同一个产品,抢到时候有但是付款的时候提示无货? AP
2.12306抢票的时候可以抢到,但是付款是提醒占座失败? AP
3.京东,淘宝的秒杀…AP
4.付款时没遇到过数据变化的吧 CP
…这种要求数据准确性比较高的必须是CP原则

你可能感兴趣的:(微服务)