乐趣区

springcloud项目优雅重启四整体缓存时间

从入口按顺序:

  • Ribbon:从 eureka-client 获取服务对应的节点列表,存储在本地缓存;通过定时任务,定时刷新缓存数据,定时任务默认 30 秒执行一次。
  • Eureka-Client:

    • 启动之后会启动定时任务,定时从 eureka-server 获取服务列表,存入本地缓存,定时任务默认 30 秒执行一次。
    • 第一次会调用全量接口获取所有服务。
    • 后续会调用增量接口,增量获取有变动的服务,根据变动信息修改缓存数据;同时根据接口返回的 code 跟本地生成的 code 做比较,如果不一致,就调用全量接口重新获取所有服务。
    • 定时 续租 /renew,默认 30 秒一次。
  • Eureka-Server:

    • 缓存:共三级缓存,可以通过配置关闭第一级缓存,默认是开启。

      1. 一级缓存readOnlyCacheMap:通过定时任务,定时从二级缓存中获取数据并刷新当前值,定时任务默认 30 秒执行一次。
      2. 二级缓存 readWriteCacheMap:通过guava cache 实现缓存机制,默认是 从写入时间起算,30 秒之后过期;服务信息有变动时,会实时修改二级缓存数据(实际上是清理掉缓存,下次读取数据时,会从下一级获取数据并存储缓存)。
      3. 三级存储 registry:从不同维度存储服务信息(比如ALL_APPS 存储所有服务列表,ALL_APPS_DELTA存储最新变更列表,服务名 存储服务对应的信息列表);服务信息有变动时,会实时修改数据。
    • 下线:定时任务定时清理长时间未 续租 /renew的节点。

      1. 定时任务默认每 60 秒执行一次。
      2. 清理掉超过 90 秒(实际上还会算上任务执行的补偿时间)未 续租 /renew的节点。
      3. 单次最多清理掉 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 缓存机制》

退出移动版