简介
本文介绍SpringCloud的Eureka是如何进行续期和自我保护的。
本内容也是Java后端面试常见的问题。
续约
服务续约和服务注册非常相似,服务注册在Eureka Client程序启动之后开启,并同时开启服务续约的定时任务。
在eureka-client-1.6.2.jar的DiscoveryClient类下有renew()方法,其代码如下:
/**
* Renew with the eureka service by making the appropriate REST call
*/
boolean renew() {
EurekaHttpResponse<InstanceInfo> httpResponse;
try {
httpResponse = eurekaTransport.registrationClient.sendHeartBeat(instanceInfo.getAppName(),
instanceInfo.getId(), instanceInfo, null);
logger.debug("{} - Heartbeat status: {}", PREFIX + appPathIdentifier, htt
pResponse.getStatusCode());
if (httpResponse.getStatusCode() == 404) {
REREGISTER_COUNTER.increment();
logger.info("{} - Re-registering apps/{}", PREFIX + appPathIdentifier,
instanceInfo.getAppName());
return register();
}
return httpResponse.getStatusCode() == 200;
} catch (Throwable e) {
logger.error("{} - was unable to send heartbeat!", PREFIX + appPathIdentifier, e);
return false;
}
}
另外,EurekaServer的续约接口在eureka-core:1.6.2.jar的com.netflix.eureka包下的InstanceResource类下,接口方法为renewLease(),它是一个RESTfulAPI接口。为了减少本章的篇幅,省略了大部分代码的展示。其中有一个registry.renew()方法,即服务续约,代码如下:
@PUT
public Response renewLease(...参数省略){
// 代码省略
boolean isSuccess=registry.renew(app.getName(),id, isFromReplicaNode);
// 代码省略
}
可以跟踪 registry.renew 的代码继续深入研究,和追踪服务注册的源码类似,在此不再赘述。另外服务续约有两个参数是可以配置的,即 Eureka Client 发送续约心跳的时间参数和
Eureka Server 在多长时间内没有收到心跳将实例剔除的时间参数。在默认情况下,这两个参数分别为 30 秒和 90 秒,官方的建议是不要修改,如果有特殊需求还是可以调整的,只需要分别在 Eureka Client 和 Eureka Server 的配置文件 application.yml 中加以下的配置:
eureka.instance.leaseRenewalIntervalInSeconds
eureka.instance.leaseExpirationDurationInSeconds
最后,有关服务注册列表的获取、服务下线和服务剔除的源码不在这里进行跟踪解读,因为与服务注册和续约类似,有兴趣的读者可以自行研究。总的来说,通过阅读源码可以发现,
整体架构与 5.4.2 节的 Eureka 的高可用架构图完全一致。
自我保护
当有一个新的 Eureka Server 出现时,它尝试从相邻 Peer 节点获取所有服务实例注册表信息。如果从相邻的 Peer 节点获取信息时出现了故障, Eureka Server 会尝试其他的 Peer 节点。如果 Eureka Serve 能够成功获取所有的服务实例信息,则根据配置信息设置服务续约的阈值。在任何时间,如果 Eureka Serve 接收到的服务续约低于为该值配置的百分比(默认为 15 分钟内低于 85%),则服务器开启自我保护模式,即不再剔除注册列表的信息。
这样做的好处在于,如果是 Eureka Server 自身的网络问题而导致 Eureka Client 无法续约,Eureka Client 的注册列表信息不再被删除,也就是 Eureka Client 还可以被其他服务消费。在默认情况下, Eureka Server 的自我保护模式是开启的,如果需要关闭,则在配置文件添加以下代码:
eureka:
server:
enable-self-preservation: false
其他网址
《深入理解Spring Cloud与微服务构建》=> 5.4 源码解析Eureka
https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance#resilience