写点什么

详解 Eureka 缓存机制

  • 2019-05-10
  • 本文字数:3511 字

    阅读完需:约 12 分钟

详解 Eureka 缓存机制

详解 Eureka 缓存机制

引言

Eureka 是 Netflix 开源的、用于实现服务注册和发现的服务。Spring Cloud Eureka 基于 Eureka 进行二次封装,增加了更人性化的 UI,使用更为方便。但是由于 Eureka 本身存在较多缓存,服务状态更新滞后,最常见的状况是:服务下线后状态没有及时更新,服务消费者调用到已下线的服务导致请求失败。本文基于 Spring Cloud Eureka 1.4.4.RELEASE,在默认 region 和 zone 的前提下,介绍 Eureka 的缓存机制。

AP 特性

从 CAP 理论看,Eureka 是一个 AP 系统,优先保证可用性(A)和分区容错性§,不保证强一致性©,只保证最终一致性,因此在架构中设计了较多缓存。



(Eureka 高可用架构)

服务状态

Eureka 服务状态 enum 类:com.netflix.appinfo.InstanceInfo.InstanceStatus


状态说明状态说明
UP在线OUT_OF_SERVICE失效
DOWN下线UNKNOWN未知
STARTING正在启动

Eureka Server

在 Eureka 高可用架构中,Eureka Server 也可以作为 Client 向其他 server 注册,多节点相互注册组成 Eureka 集群,集群间相互视为 peer。Eureka Client 向 Server 注册、续约、更新状态时,接受节点更新自己的服务注册信息后,逐个同步至其他 peer 节点。


【注意】如果 server-A 向 server-B 节点单向注册,则 server-A 视 server-B 为 peer 节点,server-A 接受的数据会同步给 server-B,但 server-B 接受的数据不会同步给 server-A。

缓存机制

Eureka Server 存在三个变量:(registry、readWriteCacheMap、readOnlyCacheMap)保存服务注册信息,默认情况下定时任务每 30s 将 readWriteCacheMap 同步至 readOnlyCacheMap,每 60s 清理超过 90s 未续约的节点,Eureka Client 每 30s 从 readOnlyCacheMap 更新服务注册信息,而 UI 则从 registry 更新服务注册信息。



三级缓存


缓存类型说明
registryConcurrentHashMap实时更新,类AbstractInstanceRegistry成员变量,UI端请求的是这里的服务注册信息
readWriteCacheMapGuava Cache/LoadingCache实时更新,类ResponseCacheImpl成员变量,缓存时间180秒
readOnlyCacheMapConcurrentHashMap周期更新,类ResponseCacheImpl成员变量,默认每30s从readWriteCacheMap更新,Eureka client默认从这里更新服务注册信息,可配置直接从readWriteCacheMap更新


缓存相关配置


配置默认说明
eureka.server.useReadOnlyResponseCachetrueClient从readOnlyCacheMap更新数据,false则跳过readOnlyCacheMap直接从readWriteCacheMap更新
eureka.server.responsecCacheUpdateIntervalMs30000readWriteCacheMap更新至readOnlyCacheMap周期,默认30s
eureka.server.evictionIntervalTimerInMs60000清理未续约节点(evict)周期,默认60s
eureka.instance.leaseExpirationDurationInSeconds90清理未续约节点超时时间,默认90s


关键类


类名说明
com.netflix.eureka.registry.AbstractInstanceRegistry保存服务注册信息,持有registry和responseCache成员变量
com.netflix.eureka.registry.ResponseCacheImpl持有readWriteCacheMap和readOnlyCacheMap成员变量

Eureka Client

Eureka Client 存在两种角色:服务提供者服务消费者,作为服务消费者一般配合 Ribbon 或 Feign(Feign 内部使用 Ribbon)使用。Eureka Client 启动后,作为服务提供者立即向 Server 注册,默认情况下每 30s 续约(renew);作为服务消费者立即向 Server 全量更新服务注册信息,默认情况下每 30s 增量更新服务注册信息;Ribbon 延时 1s 向 Client 获取使用的服务注册信息,默认每 30s 更新使用的服务注册信息,只保存状态为 UP 的服务。


二级缓存


缓存类型说明
localRegionAppsAtomicReference周期更新,类DiscoveryClient成员变量,Eureka Client保存服务注册信息,启动后立即向Server全量更新,默认每30s增量更新
upServerListZoneMapConcurrentHashMap周期更新,类LoadBalancerStats成员变量,Ribbon保存使用且状态为UP的服务注册信息,启动后延时1s向Client更新,默认每30s更新


缓存相关配置


配置默认说明
eureka.instance.leaseRenewalIntervalInSeconds30Eureka Client 续约周期,默认30s
eureka.client.registryFetchIntervalSeconds30Eureka Client 增量更新周期,默认30s(正常情况下增量更新,超时或与Server端不一致等情况则全量更新)
ribbon.ServerListRefreshInterval30000Ribbon 更新周期,默认30s


关键类


类名说明
com.netflix.discovery.DiscoveryClientEureka Client 负责注册、续约和更新,方法initScheduledTasks()分别初始化续约和更新定时任务
com.netflix.loadbalancer.PollingServerListUpdaterRibbon 更新使用的服务注册信息,start初始化更新定时任务
com.netflix.loadbalancer.LoadBalancerStatsRibbon,保存使用且状态为UP的服务注册信息

默认配置下服务消费者最长感知时间

Eureka Client时间说明
上线30(readOnly)+30(Client)+30(Ribbon)=90sreadWrite -> readOnly -> Client -> Ribbon 各30s
正常下线30(readonly)+30(Client)+30(Ribbon)=90s服务正常下线(kill或kill -15杀死进程)会给进程善后机会,DiscoveryClient.shutdown()将向Server更新自身状态为DOWN,然后发送DELETE请求注销自己,registry和readWriteCacheMap实时更新,故UI将不再显示该服务实例
非正常下线30+60(evict)*2+30+30+30=240s服务非正常下线(kill -9杀死进程或进程崩溃)不会触发DiscoveryClient.shutdown()方法,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 更新。


因此,极限情况下服务消费者最长感知时间将无限趋近 240s。


应对措施

服务注册中心在选择使用 Eureka 时说明已经接受了其优先保证可用性(A)和分区容错性§、不保证强一致性©的特点。如果需要优先保证强一致性©,则应该考虑使用 ZooKeeper 等 CP 系统作为服务注册中心。分布式系统中一般配置多节点,单个节点服务上线的状态更新滞后并没有什么影响,这里主要考虑服务下线后状态更新滞后的应对措施。

Eureka Server

  1. 缩短 readOnlyCacheMap 更新周期。缩短该定时任务周期可减少滞后时间。

  2. 关闭 readOnlyCacheMap。中小型系统可以考虑该方案,Eureka Client 直接从 readWriteCacheMap 更新服务注册信息。

Eureka Client

  1. 服务消费者使用容错机制。如 Spring Cloud Retry 和 Hystrix,Ribbon、Feign、Zuul 都可以配置 Retry,服务消费者访问某个已下线节点时一般报 ConnectTimeout,这时可以通过 Retry 机制重试下一个节点。

  2. 服务消费者缩短更新周期。Eureka Client 和 Ribbon 二级缓存影响状态更新,缩短这两个定时任务周期可减少滞后时间,例如配置:

  3. 服务提供者保证服务正常下线。服务下线时使用 kill 或 kill -15 命令,避免使用 kill -9 命令,kill 或 kill -15 命令杀死进程时将触发 Eureka Client 的 shutdown()方法,主动删除 Server 的 registry 和 readWriteCacheMap 中的注册信息,不必依赖 Server 的 evict 清除。

  4. 服务提供者延迟下线。服务下线之前先调用接口使 Eureka Server 中保存的服务状态为 DOWN 或 OUT_OF_SERVICE 后再下线,二者时间差根据缓存机制和配置决定,比如默认情况下调用接口后延迟 90s 再下线服务即可保证服务消费者不会调用已下线服务实例。

网关实现服务下线实时感知

在软件工程中,没有一个问题是中间层解决不了的,而网关是服务提供者和服务消费者的中间层。以 Spring Cloud Zuul 网关为例,网关作为 Eureka Client 保存了服务注册信息,服务消费者通过网关将请求转发给服务提供者,只需要做到服务提供者下线时通知网关在自己保存的服务列表中使该服务失效。为了保持网关的独立性,可实现一个独立服务接收下线通知并协调网关集群。


原文链接


http://college.creditease.cn/detail/243


2019-05-10 08:0012894

评论 1 条评论

发布
用户头像
女子
2019-05-11 23:30
回复
没有更多了
发现更多内容

ipvs localhost 为何不正常

Geek_f24c45

k8s IPVS kube-proxy

【混合云】部分混合云管理平台大汇总

行云管家

云计算 公有云 混合云 云管平台

多级缓存 && 分库分表

空空

架构设计

安全攻防实战系列MSF

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

Redis 6.X Cluster 集群搭建

码哥字节

redis cluster 签约计划第二季

vivo 敏感词匹配系统的设计与实践

vivo互联网技术

服务器 内容审核 架构设计实战 文本检测

目前市面上堡垒机的品牌有哪些?采购时候需要考虑哪些?

行云管家

网络安全 等保 堡垒机 等级保护

【Promise 源码学习】第十三篇 - Promise.allsettled 和 Promise.any 的实现

Brave

源码 Promise 12月日更

AI模型也需要资产管理,星环科技重磅推出AI运营平台MLOps 星环科技 星环科技

星环科技

AI

架构模式及其应用 | 内部分享

空空

内容合集 签约计划第二季

未来“数”于你 | 墨天轮携手 Vertica 发布技术文章征集令,双重大奖蓄势待“发”

墨天轮

数据库 征文大赛 vertica

信也科技 x StarRocks:打造统一销售数据平台

StarRocks

数据库 高并发 StarRocks

网易应用创新开发者大赛成功在杭举办,十强队伍现场比拼

网易云信

人工智能 音视频 直播

即时通讯(IM)开源项目OpenIM本周版本发布-v1.0.6

OpenIM

Android C++系列:Linux线程(三)线程属性

轻口味

android 28天写作 12月日更

Redis 的事务支持 ACID 么?

码哥字节

redis 事务 ACID 签约计划第二季

质量基础设施“一站式”服务信息平台建设,NQI一站式服务平台

电微13828808271

浅谈Java编译优化之常量折叠技术

码农参上

编译器优化 签约计划第二季

单库单应用 && 内容分发

空空

架构设计

动图图解GC算法 - 让垃圾回收动起来!

码农参上

垃圾回收 垃圾回收算法 签约计划第二季

区块链电子签章平台搭建,区块链电子合同系统

电微13828808271

智慧社区综合管理平台解决方案,智慧社区一体化管理系统开发

电微13828808271

弹性伸缩 && 多机房

空空

架构设计

查询分离

空空

架构设计

微服务

空空

架构设计

蒙娜丽莎Rap的秘密!这个AI算法绝不能错过!!!

百度开发者中心

AI

热门Scrum敏捷看板工具

顿顿顿

项目管理 Scrum 敏捷开发 研发管理 产品研发

可视化埋点在 React Native 中的实践

Shopee技术团队

大前端 可视化 埋点 React Native

Smack库 XMPP Tigase异常SASLErrorException

Changing Lin

12月日更

偷天换日,用JavaAgent欺骗你的JVM

码农参上

字节码插桩 代理 探针 签约计划第二季

编译优化后,for循环中i++和++i究竟哪个效率高?

码农参上

字节码 编译优化 签约计划第二季

详解 Eureka 缓存机制_架构_冯永彪_InfoQ精选文章