Eureka 注册中心原理
通过前面我们知道Eureka 提供了两个组件:Eureka Server和Eureka Client。Eureka Server提供服务发现的能力,各个微服务启动时,会向Eureka Server注册自己的信息(IP、端口、微服务实例名称),Eureka Server存储这些消息。Eureka Client是一个客户端,服务启动后,通过Eureka Client周期性心跳(默认30秒)Eureka Server发送心跳续约。Eureka Server会接收Eureka Client的心跳,如果在一定时间内没有接收到某个服务的心跳(默认90秒),会注销该实例。一般情况下简单的注册中心都包含三个组件:注册、存储和心跳。
Eureka API
Eureka Server 不仅仅可以用于Spring Cloud 应用程序,也可以用于注册其他类型的服务,因为其专门提供了一组用于注册服务的API。该Spring Cloud版本的API在eureka-core jar包中的com.netflix.eureka.resource包中,如下表为 Eureka Server 提供的Restful风格的API:
请求方式 | URL | 说明 |
GET | http://ip:port/eureka/apps | 查询所有实例 |
GET | http://ip:port/eureka/apps/[appId] | 根据appId查询 |
GET | http://ip:port/eureka/apps/[appId]/[instanceId] | 根据appId和instanceId查询 |
GET | http://ip:port/eureka/instances/[instanceId] | 根据instanceId查询 |
DELETE | http://ip:port/eureka/apps/[appId]/[instanceId] | 注销应用实例 |
POST | http://ip:port/eureka/apps/[appId] | 注册新应用实例 |
PUT | http://ip:port/eureka/apps/[appId]/[instanceId]/status?value=OUT_OF_SERVICE | 暂停下线应用实例 |
PUT | http://ip:port/eureka/apps/[appId]/[instanceId]/status?value=UP | 恢复应用实例 |
PUT | http://ip:port/eureka/apps/[appId]/[instanceId] | 发送实例心跳 |
PUT | http://ip:port/eureka/apps/[appId]/[instanceId]/metadata?version=1.1.1 | 修改应用实例元数据 |
GET | http://ip:port/eureka/status | 公开有关对等节点的信息 |
GET | http://ip:port/eureka/vips/[vipAddress] | 根据vip地址查询 |
GET | http://ip:port/eureka/svips/[svipAdress] | 根据svip地址查询 |
Eureka 状态信息与健康检测
Eureka实例的状态页和健康指示器分别默认为/info和/health,这是Spring Boot Actuator应用程序中可用端点的默认位置。如果使用非默认上下文路径或Servlet路径(如server.servlet path=/custom),则你需要改变这些甚至是改变Actuator应用程序。以下示例显示了两个设置的默认值:
eureka:
instance:
statusPageUrlPath: ${server.servletPath}/info
healthCheckUrlPath: ${server.servletPath}/health
默认情况下,Eureka使用客户端心跳来确定客户端是否启动。除非另有规定,否则Discovery Client不会根据Spring Boot Actuator传播应用程序的当前健康检查状态。因此,注册成功后,Eureka总是宣布应用程序处于“UP”状态。通过启用Eureka运行状况检查可以更改此行为,这将导致向Eureka传播应用程序状态。因此,每个其他应用程序都不会将信息发送到除“UP”之外的其他状态的应用程序。以下示例显示如何为客户端启用运行状况检查:
eureka:
client:
healthcheck:
enabled: true
eureka.client.healthcheck.enabled=true仅仅在application.yml中设置。在bootstrap.yml中设置该值会导致不良的副作用,例如在Eureka中以未知状态注册。如果您需要对健康检查进行更多控制,请考虑实现自己的com.netflix.appinfo.HealthCheckHandler。
高可用:Zones和Regions
在分布式集群中,任何服务都不允许存在单点服务,包括注册中心也是一样,我们也可以将Eureka Server作为服务注册到注册中心。从而实现高可用注册中心,示例图如下:
上图是一个最简单的Eureka 集群方案,并不是这里介绍的重点,因为如果将所有服务器部署在一个地方,一旦该地方网路瘫痪或者大部分地区停电,就会导致整个系统不能使用,为了解决该问题,Eureka 为我们提供了Zones和Regions方案。
Region Availability Zone均是AWS的概念。其中Region表示AWS中的地里位置,每个Region都有多个Availability Zone,各个Region之间完全隔离,通过这种方式实现最大的容错和稳定性。Spring Cloud默认使用的Region是us-east-1,在非AWS环境下,可以将Availability Zone理解为机房,可以将Region理解为跨机房的Eureka集群。如下为该部署方案的示例图:
通过运行多个实例并要求它们彼此注册,可以使得Eureka更具弹性和可用性。实际上,这是默认行为,因此要使其正常工作,只需向对等端添加一个有效的serviceUrl,如下例所示:
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2/eureka/
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1/eureka/
在前面的示例中,可以使用YAML文件,在不同的Spring配置文件中运行它来在两个主机(peer1和peer2)上运行同一个服务。您可以通过操纵/etc/hosts来解析主机名,使用此配置来测试单个主机上的对等意识(在生产中这样做没有多大价值)。事实上,如果您在一台知道自己主机名的机器上运行(在默认情况下,它是通过使用 java.net.InetAddress), eureka.instance.hostname配置就不再需要了。
您可以向一个系统添加多个对等点,只要它们都通过至少一个边缘彼此连接,它们就可以在彼此之间同步注册。如果对等点在物理上是分开的(在一个数据中心内或在多个数据中心之间),那么系统原则上可以经受“split-brain”类型的故障。您可以向一个系统中添加多个对等点,只要它们都直接连接在一起,它们就可以在彼此之间同步注册。
eureka:
client:
serviceUrl:
defaultZone: http://peer1/eureka/,http://peer2/eureka/,http://peer3/eureka/
---
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
---
spring:
profiles: peer3
eureka:
instance:
hostname: peer3
关于更多Spring Cloud Netflix Cloud Eureka 可以参考 Spring Cloud官方文档。后续我们讲解负载均衡、网关路由等还会用到Eureka。