从入口按顺序:
- Ribbon:从
eureka-client
获取服务对应的节点列表,存储在本地缓存;通过定时任务,定时刷新缓存数据,定时任务默认 30 秒执行一次。 -
Eureka-Client:
- 启动之后会启动定时任务,定时从
eureka-server
获取服务列表,存入本地缓存,定时任务默认 30 秒执行一次。 - 第一次会调用全量接口获取所有服务。
- 后续会调用增量接口,增量获取有变动的服务,根据变动信息修改缓存数据;同时根据接口返回的
code
跟本地生成的code
做比较,如果不一致,就调用全量接口重新获取所有服务。 - 定时
续租 /renew
,默认 30 秒一次。
- 启动之后会启动定时任务,定时从
-
Eureka-Server:
-
缓存:共三级缓存,可以通过配置关闭第一级缓存,默认是开启。
- 一级缓存
readOnlyCacheMap
:通过定时任务,定时从二级缓存中获取数据并刷新当前值,定时任务默认 30 秒执行一次。 - 二级缓存
readWriteCacheMap
:通过guava cache
实现缓存机制,默认是从写入时间起算,30 秒之后过期
;服务信息有变动时,会实时修改二级缓存数据(实际上是清理掉缓存,下次读取数据时,会从下一级获取数据并存储缓存)。 - 三级存储
registry
:从不同维度存储服务信息(比如ALL_APPS
存储所有服务列表,ALL_APPS_DELTA
存储最新变更列表,服务名
存储服务对应的信息列表);服务信息有变动时,会实时修改数据。
- 一级缓存
-
下线:定时任务定时清理长时间未
续租 /renew
的节点。- 定时任务默认每 60 秒执行一次。
- 清理掉超过 90 秒(实际上还会算上任务执行的补偿时间)未
续租 /renew
的节点。 - 单次最多清理掉 25% 的节点。
-
整体流程如下:
相关配置:
Ribbon:
配置参数 | 默认(秒) | 说明 |
---|---|---|
ribbon.ServerListRefreshInterval | 30 | 本地服务列表缓存更新周期 |
Euraka-Client:
配置参数 | 默认(秒) | 说明 |
---|---|---|
eureka.client.registryFetchIntervalSeconds | 30 | 本地服务列表缓存更新周期,(正常情况下增量更新,第一次或与 Server 端不一致等情况则全量更新) |
eureka.instance.leaseRenewalIntervalInSeconds | 30 | 续约周期 |
Euraka-Server:
配置参数 | 默认(秒) | 说明 |
---|---|---|
eureka.server.useReadOnlyResponseCache | true | 是否开启 readOnlyCacheMap 缓存 |
eureka.server.responsecCacheUpdateIntervalMs | 30 |
readOnlyCacheMap 缓存更新周期 |
eureka.server.evictionIntervalTimerInMs | 60 | 清理 / 下线长时间未续租节点周期 |
eureka.instance.leaseExpirationDurationInSeconds | 90 | 未续租节点超时时间,超过这个时间,就会被清理任务清理掉 |
默认配置下服务消费者最长感知时间:
Eureka-Client | 时间(秒) | 说明 |
---|---|---|
上线 | 30(readOnly)+30(Client)+30(Ribbon)=90 | readWrite -> readOnly -> Client -> Ribbon 各 30s |
正常下线 | 30(readonly)+30(Client)+30(Ribbon)=90 | 服务正常下线(kill 或 kill -15 杀死进程)会给进程善后机会,<br/>DiscoveryClient.shutdown() 将向 Server 更新自身状态为 DOWN,<br/> 然后发送 DELETE 请求注销自己,registry 和 readWriteCacheMap 实时更新,故 UI 将不再显示该服务实例 |
非正常下线 | 60+90+30+30+30=240 | 服务非正常下线(kill -9 杀死进程或进程崩溃)不会触发 DiscoveryClient.shutdown() 方法,<br/>Eureka Server 将依赖每 60s 清理超过 90s 未续约服务从 registry 和 readWriteCacheMap 中删除该服务实例 |
考虑如下情况:
- 0s 时服务未通知 Eureka Client 直接下线;
- 29s 时第一次过期检查 evict 未超过 90s;
- 89s 时第二次过期检查 evict 未超过 90s;
- 149s 时第三次过期检查 evict 未续约时间超过了 90s,故将该服务实例从 registry 和 readWriteCacheMap 中删除;
- 179s 时定时任务从 readWriteCacheMap 更新至 readOnlyCacheMap;
- 209s 时 Eureka Client 从 Eureka Server 的 readOnlyCacheMap 更新;
- 239s 时 Ribbon 从 Eureka Client 更新。
由于 eureka-server
分批下线机制(最多 25%),如果同时有大批量节点下线的话(超过 25%,未达到自我保护机制阈值,或者未开启自我保护机制),有的服务节点还会超过 240 秒。
参考:
《详解 Eureka 缓存机制》