5.4 Eureka核心概念
5.4.1 服务注册
服务注册是一个服务生命周期的起点,在服务实例启动的时候,它会向注册中心发送一条注册指令。服务注册指令包含以下几个主要内容:
1. 服务名称
服务名称通常默认是应用名称(也就是Spring的配置项中配置的application.name),我们也可以指定一个自定义的服务名,它用来告诉注册中心当前注册的服务名称。
2. 寻址信息
寻址信息是当前服务实例的网络地址信息,比如hostname、IP地址和端口号,调用方服务在获取目标服务地址之后才能发起调用。本机测试往往采用IP地址加端口号的配置方式,在线上生产环境中往往采用DNS域名即hostname的方式,这样可以有效防止内网IP地址漂移,从而导致服务地址失效。
3. 服务状态
服务状态包括可用、不可用、初始化、已下线等。
4. 注册时间
注册时间是指服务实例向注册中心发起注册的时间。
服务注册所包含的信息量不多,并不会占用太多存储空间,因此一个注册中心实例就可以为大量服务节点提供服务治理功能。尽管如此,我们在高可用的架构之下,仍然需要将注册中心搭建成一个集群,集群内的注册中心会将本地的服务注册表同步到其他注册中心,服务实例只要向一个注册中心发送注册指令,这条指令就会被同步给整个注册中心集群。
5.4.2 服务发现
Eureka属于一个客户端负载均衡的服务治理系统,由消费者来决定向哪一个生产者发起调用请求。在这个模式下,消费者服务就要知道所有已注册的机器的地址信息。为了保证消费者在本地有最新的服务器列表,消费者服务每隔一段时间都要从注册中心读取最新的服务地址和状态,然后刷新本地的服务器列表,这个周而复始的过程就叫作服务发现。
服务在注册中心的状态码如下:
UP:服务处于正常运行阶段。
DOWN:服务已下线。
STARTING:服务正在启动中。
OUT_OF_SERVICE:服务强制下线。
UNKNOWN:未知状态。
5.4.3 服务续约和服务下线
服务节点可能存在非正常下线的情况,比如由于网络问题导致无法提供服务,那么注册中心就要知道当前服务是否处于可用状态,并将服务状态写入本地注册表中。这样,服务消费者就可以通过服务发现机制从注册表中获取处于可用状态的服务器列表。
注册中心获取服务状态的方案有两种,一种是注册中心定时发起HealthCheck检查,另一种是由客户端定时上报自己的状态到注册中心。Eureka采取的是第二种方案,每隔一段时间(这个时间间隔是可配置的),服务节点就会向注册中心发送一个“心跳包”,上报当前节点的最新状态,我们称这个过程为“服务续约”。
服务下线是由服务提供者主动发起的下线指令,注册中心在收到服务下线指令后,会将这台服务器标记成“Down”的状态。
5.4.4 服务剔除
正常运行的服务每隔一段时间都会主动发起服务续约,在一些异常情况下(比如服务无响应或者由于网络原因导致心跳包无法送达注册中心),如果注册中心在规定时间内始终没有收到服务续约的请求,那么它将对服务做自动下线处理。我们将这个过程称为“服务剔除”,服务剔除是由注册中心发起的一项定时任务,用来清除不可用的服务实例。
5.4.5 服务自保
在实际的生产环境中,服务剔除有可能会“误杀”正常服务,比如某个机房产生了短暂的网络抖动,导致所有服务实例与注册中心之间的网络通信短暂不可用,但这些服务实例仍然可以对外部用户提供服务。在这种极端情况下,如果我们开启了服务剔除功能,那么就有可能将所有服务剔除下线,造成大范围宕机。
Eureka内部有一套服务自保机制,它会在运行期持续统计过去15分钟内服务续约的成功率,如果成功率低于85%(该项数值可以在配置文件中指定),那么将主动开启服务自保模式,在注册中心处于自保模式期间,服务剔除功能将不再生效。由此可见,服务剔除和服务自保在同一时刻只能有一个功能生效,我们可以通过配置项关闭服务自保功能。