SpringCloud微服务技术(二)——SpringCloud组件之Eureka

Eureka介绍

Eureka是什么

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

Eureka与spring-cloud的关系

Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现

Eureka能做什么

Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心

核心功能点

在这里插入图片描述

  • 服务注册(register):Eureka Client会通过发送REST请求的方式向Eureka Server注册自己的服务,提供自身的元数据,比如ip地址、端口、运行状况指标的url、主页地址等信息。Eureka Server接收到注册请求后,就会把这些元数据信息存储在一个双层的Map中。
  • 服务续约(renew):在服务注册后,Eureka Client会维护一个心跳来持续通知Eureka Server,说明服务一直处于可用状态,防止被剔除。Eureka Client在默认的情况下会每隔30秒(eureka.instance.leaseRenewallIntervalInSeconds)发送一次心跳来进行服务续约。
  • 服务同步(replicate):Eureka Server之间会互相进行注册,构建Eureka Server集群,不同Eureka Server之间会进行服务同步,用来保证服务信息的一致性。
  • 获取服务(get registry):服务消费者(Eureka Client)在启动的时候,会发送一个REST请求给Eureka Server,获取上面注册的服务清单,并且缓存在Eureka Client本地,默认缓存30秒(eureka.client.registryFetchIntervalSeconds)。同时,为了性能考虑,Eureka Server也会维护一份只读的服务清单缓存,该缓存每隔30秒更新一次。
  • 服务调用:服务消费者在获取到服务清单后,就可以根据清单中的服务列表信息,查找到其他服务的地址,从而进行远程调用。Eureka有Region和Zone的概念,一个Region可以包含多个Zone,在进行服务调用时,优先访问处于同一个Zone中的服务提供者。
  • 服务下线(cancel):当Eureka Client需要关闭或重启时,就不希望在这个时间段内再有请求进来,所以,就需要提前先发送REST请求给Eureka Server,告诉Eureka Server自己要下线了,Eureka Server在收到请求后,就会把该服务状态置为下线(DOWN),并把该下线事件传播出去。
  • 服务剔除(evict):有时候,服务实例可能会因为网络故障等原因导致不能提供服务,而此时该实例也没有发送请求给Eureka Server来进行服务下线,所以,还需要有服务剔除的机制。EurekaServer在启动的时候会创建一个定时任务,每隔一段时间(默认60秒),从当前服务清单中把超时没有续约(默认90秒,eureka.instance.leaseExpirationDurationInSeconds)的服务剔除。
  • 自我保护:既然Eureka Server会定时剔除超时没有续约的服务,那就有可能出现一种场景,网络一段时间内发生了异常,所有的服务都没能够进行续约,Eureka Server就把所有的服务都剔除了,这样显然不太合理。所以,就有了自我保护机制,当短时间内,统计续约失败的比例,如果达到一定阈值,则会触发自我保护的机制,在该机制下, Eureka Server不会剔除任何的微服务,等到正常后,再退出自我保护机制。自我保护开关(eureka.server.enable- self-preservation: false)

Eureka如何使用

  • 1.在spring-cloud项目里面加入依赖
    eureka客户端:
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

eureka服务端:

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  • 2.eureka服务端项目里面加入以下配置
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
  • 3.在spring-boot启动项目上 加入注解:@EnableEurekaServer 就可以启动项目了
@EnableEurekaServer
@SpringBootApplication
public class AppEureka {
    public static void main(String[] args) {
        SpringApplication.run(AppEureka.class);

    }
}

如果看见这个图片,那么说明你就搭建好了:
在这里插入图片描述
这个警告只是说你把他的自我保护机制关闭了

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

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

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

Eureka和Nginx在负载均衡上对比

Nginx

在这里插入图片描述
假设采用轮询机制,nginx在集群中的某个服务挂掉之后,再次轮询到该服务时,浏览器会出现刷新,但是一直无法访问该服务。
第一次刷新
在这里插入图片描述
第二次刷新
在这里插入图片描述
反复刷新,上面两种情况交替出现。
暂停power1服务,刷新浏览器
在这里插入图片描述

Eureka

而使用Eureka作为负载均衡,当某个服务挂掉之后,且超时无响应,则会剔除该挂掉的服务。
在这里插入图片描述

相关配置

EurekaServer

eureka:
  server:
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 4000 #4s清除服务 设置清理间隔

EurekaClient

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

CAP定理

一致性Consistency

写操作之后的读操作,必须返回该值。

可用性Availability

只要收到用户的请求,服务器就必须给出回应。

分区容错性Partition tolerance

大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容错的意思是,区间通信可能失败。比如,一台服务器放在本地,另一台服务器放在外地(可能是外省,甚至是外国),这就是两个区,它们之间可能无法通信。

案例说明

在分布式系统中,分区容错性必须成立,因为要保证系统服务之间可以正常通信。
如下例子:
S1 和 S2 是两台跨区的服务器,服务器上部署的是相同的系统资源
在这里插入图片描述
某条记录是 v0,用户向 S1 发起一个写操作,将其改为 v1
在这里插入图片描述
正常读取S1服务器上的资源,返回v1
在这里插入图片描述
用户有可能会向S2发起读取操作,由于s2的值没有发生变化,因此返回的是v0,所以S1和S2的读操作不一致,
在这里插入图片描述
为了让S2的返回值与S1一致,所以我们需要在往S1执行写操作的时候,让S1给S2也发送一条消息,要求s2也变成v1
在这里插入图片描述
这样子用户向s2发起读操作,就也能得到v1
在这里插入图片描述
一致性和可用性,为什么不可能同时成立?答案很简单,因为可能通信失败(即出现分区容错)。
如果保证 S2 的一致性,那么 S1 必须在写操作时,锁定 S2 的读操作和写操作。只有数据同步后,才能重新开放读写。锁定期间,S2 不能读写,可用性不成立。
如果保证 S2 的可用性,那么势必不能锁定 S2,所以一致性不成立。
综上所述,S2 无法同时做到一致性和可用性。系统设计时只能选择一个目标。如果追求一致性,那么无法保证所有节点的可用性;如果追求所有节点的可用性,那就没法做到一致性。

Eureka集群

Eureka集群原理

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

Eureka集群配置

  • 1.创建模块
    在这里插入图片描述
    如何声明集群环境的server?
    Eureka 的server会把自己的注册信息与其他的server同步,所以这里我们不需要注册到自己身上
    在这里插入图片描述
    方便理解集群 我做了一个域名的映射
    在这里插入图片描述

  • 2.Eureka1服务配置
    在这里插入图片描述

  • 3.Eureka2服务配置
    在这里插入图片描述

  • 4.Eureka3服务配置
    在这里插入图片描述

  • 5.客户端配置
    在这里插入图片描述

  • 6.启动所有服务,查看
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    由此可看出客户端服务只配置了eureka1这一个注册中心,但是eureka2,eureka3同样可以发现此客户端服务。

Eureka的高可用体现

上例停止eureka2这个服务后,eureka1,eureka3可以正常注册服务
上例停止eureka2,eureka3两个服务后,eureka1可以正常注册服务
将上例中的客户端服务修改配置如下:
在这里插入图片描述
则停止任务两个注册服务,最后一个都可以正常注册服务。

Eureka和Zookeeper对比

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

  • Eureka 不再从注册列表中移除因为长时间没有收到心跳而过期的服务。
  • Eureka 仍然能够接收新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点可用)
  • 当网络稳定后,当前实例新的注册信息会被同步到其它节点中
原创文章 38 获赞 52 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yemuxiaweiliang/article/details/105606474