Spring Cloud 服务注册中心 Netflix Eureka 介绍

Eureka简介

Spring Cloud Eureka基于Netflix Eureka开发,负责整个Spring Cloud微服务架构中的服务治理,具体来讲就是两个功能:

  • 服务注册:每个服务在启动时都需要连接到Eureka,并向Eureka提供本服务的名称、主机名、端口、通信协议等信息,Eureka则根据这些信息,按照服务名称组织好服务清单,例如:
    服务名服务提供者
    CRM-SERVICE10.0.0.1:808010.0.0.2:8080
    NEWS-SERVICE10.0.0.5:808010.0.0.6:808010.0.0.7:8080
  • 服务发现:服务间的调用无需在业务逻辑或者配置文件显式指定具体的服务实例所在的地址,而是向Eureka发起一个服务发现请求,并提供目标服务的名称,Eureka根据这个名称返回这个服务的实例地址。例如NEWS-SERVICE需要调用CRM-SERVICE服务,NEWS-SERVICE会向Eureka请求服务名称为CRM-SERVICE的实例地址,Eureka会返回该服务所有可用地址:10.0.0.1:808010.0.0.2:8080NEWS-SERVICE则会根据这个地址发起请求。当然,每个服务都需要指定Eureka服务器的地址。

Eureka包含服务器和客户端两个部分,上述是Eureka服务器的具体功能。Eureka客户端简单来说就是用来与Eureka服务器进行通信交互,例如:

  • 处理Eureka服务器提供的服务地址
  • 向Eureka服务器发起请求,注册自身(服务提供者)。
  • 发送心跳包,进行续租
  • 实时更新客户端缓存的服务清单

Eureka高可用

考虑到服务器集群可能会出现各种各样的网络、硬件故障,所以需要多个Eureka服务器实例来组成一个服务治理集群,即使其中一个Eureka服务器宕机,其它Eureka服务器依然可以继续进行服务治理,从而达到Eureka的高可用。

Eureka在集群化时,每个Eureka服务器实例会将自己作为服务,向其它Eureka服务器实例注册自己,从而各个Eureka都两两互相注册,在服务清单发生变化时,它们会互相之间进行同步。

例如有两台主机,一台主机名为eureka0,另外一台为eureka1,如果需要开启两个Eureka服务器实例并组成Eureka集群,需要进行以下配置:
eureka0配置文件application.yml

spring:
	application:
		name: eureka-server
server:
	port: 8080
eureka:
	client:
		service-url:
			default-zone: http://eureka1:8080

eureka1配置文件application.yml

# eureka1配置
spring:
	application:
		name: eureka-server
server:
	port: 8080
eureka:
	client:
		service-url:
			default-zone: http://eureka0:8080

启动上述两个实例。并使用浏览器访问http://eureka0:8080http://eureka1:8080,可以发现Instances currently registered with Eureka栏有1个Eureka服务器实例,代表这两个Eureka服务器已经成功组成Eureka服务器集群。

对于Spring Cloud微服务集群的Eureka客户端,可以在配置项eureka.client.serviceUrl.defaultZone指定多个Eureka服务器实例的地址,这样在其中一个地址对应的服务器宕机时,Eureka客户端还可以尝试连接另外一个Eureka服务器实例。


Spring Cloud微服务集群结构

Spring Cloud微服务集群有三个基本角色:服务注册中心、服务提供者、服务消费者,组成以下架构:

在这里插入图片描述

服务提供者

服务提供者与Eureka的交互主要体现在以下三个方面:

  • 服务注册
    服务提供者在启动时,会根据配置文件中配置的Eureka服务器地址列表,随机选取一个地址并连接到Eureka服务器。然后,通过发送REST请求的方式(包含自身数据)将自身注册到该Eureka服务器上。Eureka服务器收到该请求后,会将请求附带的服务节点数据存储到一个两层Map中,第一层的key为服务名,也就是上述例子中的CRM-SERVICE或者NEWS-SERVICE,第二层key为服务的实例名称appName,在源码中,这个Map定义在com.netflix.eureka.registry.AbstractInstanceRegistry中:

    private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry
                = new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();
    

    其中,InstanceInfo包含了一个服务实例的元数据信息,含有30余个实例变量,记录了服务实例ID、服务实例名、所在IP地址、端口、主页URL、健康检查URL、状态检查URL、最近更新时间等数据字段。

  • 服务同步
    对于Eureka服务器集群,一个Eureka服务器在收到服务提供者的服务注册请求后,除了会将其生成InstanceInfo保存在本地以外,还会将其转发给其它Eureka服务器实例,从而使各个Eureka服务器的服务注册清单达到同步。

  • 续租
    在默认情况下,Eureka客户端每隔20秒就会向Eureka服务器发送一个心跳包,来方便Eureka服务器判断这个服务有没有失效。如果超出90秒(默认情况)还没有收到这个服务发送的心跳包,Eureka服务器就会将服务从服务注册清单中删除。

服务消费者

服务消费者需要调用服务提供者的服务,所以与Eureka的交互大多体现在服务清单的获取和更新上:

  • 服务获取
    当服务消费者启动的时候,同样会根据配置文件中配置的Eureka服务器地址列表,随机选取一个Eureka服务器。然后,通过发送REST请求给Eureka服务器,来获取服务清单。并且在此之后,每隔30秒服务消费者都会向Eureka服务器主动请求服务清单。服务清单一般包含了服务提供者的元数据信息。
  • 服务调用
    服务消费者获取到服务清单后,就会在需要调用其它服务时根据这个清单来与服务提供者建立连接,互相通信。如果服务消费者有负载均衡的功能,并且同一个服务有多个相同的服务提供者,那么会轮询调用这些服务提供者。
服务注册中心
  • 失效服务自动剔除
    之前提到过,如果服务提供者由于种种原因宕机后,Eureka服务器就无法收到该服务发送的心跳包。Eureka默认每60秒检查一次服务提供者,对超过90秒没有收到心跳包的服务提供者会被服务注册中心剔除。

  • 自我保护
    在Eureka服务器运行期间,如果心跳包接收失败的比例在15分钟之内低于85%,Eureka服务器就会进入保护模式,不会删除服务清单中任何一个服务。这种机制也对服务消费者提了个要求:如果目标服务中的某个服务实例的确是失效了,那么需要采取“熔断”,即在这个服务实例恢复正常之前,不再调用这个服务实例,而是调用该服务的其它实例(如果有的话),如果该服务仅有一个服务实例并且失效,那么只能抛出一个异常。
    当Eureka服务器进入自我保护模式之后,会在Eureka首页展示一行红色的字:

    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

    可以将参数eureka.server.enable-self-preservation设为false停用保护机制。

Eureka Region / Zone 概念

对于存在多个机房的Spring Cloud微服务集群,我们总是希望一个服务消费者能够调用当前机房的服务提供者,而不是调用其它机房的服务提供者,因为这样可能会造成比较的大的延时,影响系统的吞吐量和客户端的体验。所以,Eureka引入了Region/Zone的概念来区分不同机房的服务提供者。

Region可以理解为地理上的分区,比如北京、上海或者扩大到亚洲、北美都是可以的,没有大小的限制,可以自己根据整个Spring Cloud的微服务集群架构或者业务结构特点来划分不同的Region。
Zone可以理解为具体的机房。例如上海有多个机房,可以将不同的机房定义为不同的ID。可以看出Region和Zone是一对多的关系:
在这里插入图片描述
服务消费者B总是会尝试调用本机房的服务提供者,如果当前机房某一服务的全部服务提供者实例失效,那么就会尝试调用另外一个机房的服务。

如果需要使用Region/Zone策略,那么需要保证每个机房至少有一个Eureka服务器实例。
我们假设上述例子中,虹口区机房Eureka服务器实例主机名为hk.eureka、浦东区机房Eureka服务器实例主机名为pd.eureka。那么hk.eurekaapplication.yml配置为:

spring:
	application:
		name: shanghai-hk-eureka
server:
	port: 8080
eureka:
	instance:
		hostname: hk.eureka             #当前实例主机名
	client:
		register-with-eureka: true      #将自己作为Eureka客户端来尝试注册自己,Eureka高可用必须
		prefer-same-zone-eureka: true   #是否采用优先选取同一Zone的服务的策略
		fetch-registry: true     # 从其它Eureka服务器实例获取服务,从而达到同步
		region: shanghai         # 当前Eureka的Region
		availability-zones:
			shanghai: hongkou, pudong  #第一个为当前Eureka服务器的Zone
		service-url:  #上述Zone所对应的Eureka服务器实例地址
			hongkou: http://${eureka.instance.hostname}:${server.port}/eureka   
			pudong: http://pd.eureka:8080/eureka

pd.eurekaapplication.yml配置为:

spring:
	application:
		name: shanghai-pd-eureka
server:
	port: 8080
eureka:
	instance:
		hostname: pd.eureka
	client:
		register-with-eureka: true
		prefer-same-zone-eureka: true
		fetch-registry: true
		region: shanghai
		availability-zones:
			shanghai: pudong, hongkou  #注意这里的顺序
		service-url:
			hongkou: http://hk.eureka:8080/eureka
			pudong: http://${eureka.instance.hostname}:${server.port}/eureka   

虹口区机房CRM-SERVICE(假定主机名为hk.crm.service)配置:

spring:
	application:
		name: crm-service
server:
	port: 8080
eureka:
	instance:
		hostname: hk.crm.service
		metadata-map:
			zone: hongkou  #指定当前Zone
	client:
		register-with-eureka: true
		prefer-same-zone-eureka: true
		fetch-registry: true
		region: shanghai
		availability-zones:  
			shanghai: hongkou, pudong
		service-url:
			hongkou: http://hk.eureka:8080/eureka
			pudong: http://pd.eureka:8080/eureka

按照上述规则配置好其它服务提供者,然后配置虹口区消费者B:

spring:
	application:
    	name: feign
server:
	port: 8080
eureka:
	instance:
		hostname: hk.feign
		metadata-map:
			zone: hongkou
	client:
		register-with-eureka: true
		prefer-same-zone-eureka: true
		fetch-registry: true
		region: shanghai
		availability-zones:  
			shanghai: hongkou, pudong
		service-url:
			hongkou: http://hk.eureka:8080/eureka
			pudong: http://pd.eureka:8080/eureka

这样,虹口区机房消费者在通过访问http://CRM-SERVICE/时是始终会优先选择当前机房的服务提供者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值