Spring Cloud服务注册发现——Eureka及其高可用

Eureka

Eureka是大名鼎鼎的Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
Eureka包含两个组件:Eureka Server和Eureka Client。
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Client是一个java客户端,用于简化与Eureka Server的交互,作为轮询负载均衡器,并提供服务的故障切换支持。
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

Eureka与Zookeeper的比较

为什么要用Eureka而不是Zookeeper?

当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是Zookeeper会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

而Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况: 

  1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
  2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
  3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中

因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。

Spring Cloud服务注册发现——Eureka及其高可用_第1张图片

Eureka Server

用Idea可以很方便的创建Eureka Server

Spring Cloud服务注册发现——Eureka及其高可用_第2张图片

配置application.yml

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    register-with-eureka: false

#  instance:
#      preferIpAddress: true
#      hostname: localhost
  server:
    #自我保护模式,测试环境关闭,生产环境一定要打开
    enable-self-preservation: false

spring:
  application:
    name: eureka-server

server:
  port: 8761

启动入口Application需要加注解@EnableEurekaServer:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

启动正常后,访问http://localhost:8761/:

Spring Cloud服务注册发现——Eureka及其高可用_第3张图片

接下来搭建测试的Eureka Client:

Spring Cloud服务注册发现——Eureka及其高可用_第4张图片

配置application.yml

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: eureka-client

启动类Application添加注解@EnableEurekaClient 或者 @EnableDiscoveryClient

注意:SpringCLoud中的“Discovery Service”有多种实现,比如:eureka, consul, zookeeper。

  • @EnableDiscoveryClient注解是基于spring-cloud-commons依赖,并且在classpath中实现; 
  • @EnableEurekaClient注解是基于spring-cloud-netflix依赖,只能为eureka作用;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientApplication {

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

启动正常后,观察Eureka Server控制台,发现有个服务成功添加到注册表

访问http://localhost:8761/

Spring Cloud服务注册发现——Eureka及其高可用_第5张图片

Eureka的高可用

由于Eureka是服务注册发现中心,如果Eureka挂了,我们整个服务就挂了。所以需要给Eureka搭建集群。

采用相互注册,即Eureka1向Eureka2注册,Eureka2向Eureka1注册。

Spring Cloud服务注册发现——Eureka及其高可用_第6张图片

创建2个Eureka

Eureka1 8761向8762注册:defaultZone: http://localhost:8762/eureka/

Eureka2 8762向8761注册:defaultZone: http://localhost:8761/eureka/

Eureka Client向Eureka1,Eureka2注册:defaultZone: http://localhost:8761/eureka/, http://localhost:8762/eureka/

改造如下:

Spring Cloud服务注册发现——Eureka及其高可用_第7张图片

application.yml:

spring:
  profiles:
    active: server1

application-server1.yml:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8762/eureka/
    # 表示是否注册自身到eureka服务器
    register-with-eureka: false
    # 是否从eureka上获取注册信息
    # fetch-registry: false

  instance:
      preferIpAddress: true
#      hostname: server1
  server:
    #自我保护模式,测试环境关闭,生产环境一定要打开
    enable-self-preservation: false

spring:
  application:
    name: eureka-server1

server:
  port: 8761

application-server2.yml:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    # 表示是否注册自身到eureka服务器
    register-with-eureka: false
    # 是否从eureka上获取注册信息
    # fetch-registry: false

  instance:
      preferIpAddress: true
#      hostname: server2
  server:
    #自我保护模式,测试环境关闭,生产环境一定要打开
    enable-self-preservation: false

spring:
  application:
    name: eureka-server2

server:
  port: 8762

启动两个实例:

Spring Cloud服务注册发现——Eureka及其高可用_第8张图片

Spring Cloud服务注册发现——Eureka及其高可用_第9张图片

访问http://localhost:8761/,发现Eureka1中注册了Client

Spring Cloud服务注册发现——Eureka及其高可用_第10张图片

访问http://localhost:8762/,发现Eureka2中注册了Client。

Spring Cloud服务注册发现——Eureka及其高可用_第11张图片

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