本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Netflix Eureka 目录汇总
-
eureka server启动以及初始化
-
eureka client启动以及初始化
-
服务注册
3.1 可重入读写锁-读锁
-
服务发现
4.1. 全量抓取注册表
4.2. 注册表多级缓存机制
4.3. 注册表多级缓存过期机制(主动、定时、被动)
4.4. 增量抓取注册表
4.4.1. 一致性Hash对比机制 4.4.2. 可重入读写锁-写锁 -
服务续约
-
服务下线
-
服务故障自动感知及服务实例自动摘除
Netflix Eureka 时间间隔简要
服务注册-
服务发现-
读写缓存-定时过期(180秒)
只读缓存-被动过期(30秒(整30秒))
定时抓取增量注册表(30秒)
定时删除超过3分钟的服务实例变更记录(30秒)
服务续约(30秒)
服务下线
服务故障自动感知及服务实例自动摘除(感知:90秒(BUG:90 * 2秒);摘除:60秒)
服务故障自动感知及服务实例自动摘除(心跳超时自动剔除)
补偿时间机制
Lease.isExpired() BUG
分批摘取机制
随机摘取机制
服务主动下线
假如eureka client主动停机,调用DiscoveryClient.shutdown()方法,就会发送请求到eureka server去下线一个服务实例。
服务故障自动摘除
假如eureka client意外宕机,没有机会调用DiscoveryClient.shutdown()方法,也不会去发送请求到eureka server下线服务实例。
自动故障感知以服务实例摘除机制
eureka依靠定时心跳感知服务实例是否正常。如果服务意外宕机,就不会再发送心跳。如果在一段时间内没有接收到某个服务的心跳,那么就将这个服务实例给摘除,认为这个服务实例已经宕机了。
EurekaBootStrap::registry.openForTraffic(applicationInfoManager, registryCount)
eureka server在启动初始化的时候调用registry.openForTraffic(applicationInfoManager, registryCount)方法初始化注册表(registry)的自动故障感知以服务实例摘除任务线程。
PeerAwareInstanceRegistry.openForTraffic()方法里,调用super.postInit()。每隔60s运行一次定时调度的后台线程任务EvictionTask。
AtomicReference evictionTaskRef.set(new EvictionTask()):对EvictionTask任务的原子引用,保证并发情况下对new EvictionTask()对象的引用的原子操作。
服务故障自动感知及自动摘除流程
(1)获取一个补偿时间,避免EvictionTask两次调度的时间超过了设置的60s。(补偿时间的机制)
(2)遍历注册表中所有的服务实例,然后调用Lease.isExpired()方法,来判断当前这个服务实例的租约是否过期了,是否失效了,服务实例故障了,如果是故障的服务实例,加入一个列表。如果上次的心跳到现在间隔了90s * 2 = 180s,3分钟,才会认为是故障了。 (eureka bug)
lastUpdateTimestamp:最后一次更新的时间戳(最后一次续约更新的时间戳 lastUpdateTimestamp = System.currentTimeMillis() + duration)
duration:90秒
additionalLeaseMs:补偿时间 (上次任务执行延迟时长,避免由于上次任务延迟完成而误判是超过60秒(任务间隔)还没有收到心跳认为心跳超时)
---
additionalLeaseMs 可以认为是 lastUpdateTimestamp 的偏移量。
lastUpdateTimestamp+=additionalLeaseMs 作为最后一次续约的时间戳。
isExpired :当前时间 > 调整后的续约时间戳(此处多加了duration秒) + duration 才算过期
(3)不会一次性将所有故障的服务实例都摘除,每次最多将注册表中15%的服务实例放入expiredLeases集合中(可以过期剔除的服务实例,并不一定会被剔除),并不会一次摘除所有的故障实例,下次EvictionTask再次执行的时候,会再次摘除,分批摘取机制
(4)在摘除的时候,是从故障实例集合(expiredLeases)中随机挑选本次可以摘除的服务实例摘除。 (随机摘取机制)
(5)摘除服务实例的时候,其实就是调用下线的方法,AbstractInstanceRegistry.internelCancel()方法(注册表、下线时间戳、最近状态变更队列、清除缓存)