【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

详解 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:0012520

评论 1 条评论

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

使用 DataEase 展示服务器运行状态

搞大屏的小北

Linux监控 Linux监控脚本 监控展示 监控大屏

AI又火了,这一次云厂商能赚到钱吗?

脑极体

云计算 AI 云厂商

“ChatGPT们”的淘金时代

OneFlow

电商通用型商品中心设计

京东科技开发者

构架 企业号 3 月 PK 榜 电商中心 SKU 类目

机器学习实战系列[一]:工业蒸汽量预测(最新版本下篇)含特征优化模型融合等

汀丶人工智能

数据挖掘 机器学习 数学建模

「高频必考」Docker&K8S面试题和答案

王中阳Go

Docker 高效工作 学习方法 面试题 Go 语言

拯救脂肪肝第一步!以飞桨3D医疗影像分割方案MedicalSeg自主诊断脂肪肝

飞桨PaddlePaddle

深度学习 计算机视觉 语义分割 PaddlePaddle

阿里内部进阶学习SpringBoot+Vue全栈开发实战文档

三十而立

深入探讨Python Tornado框架:原理与异步实现

阿呆

Python tornado Web

职场「OKR」,魔幻又内卷

Java 架构 职场 OKR

秒懂算法 | Treap树

TiAmo

数据结构 算法 节点 旋转法

AIGC热门技术岗平均年薪超百万,脉脉林凡认为白领可能先于蓝领失业

科技热闻

AIGC时代:未来已来

华为云开发者联盟

人工智能 华为云 AIGC 华为云开发者联盟 企业号 3 月 PK 榜

标星90K,这份Leetcode刷题手册在GitHub爆火!完整版开放下载

架构师之道

Java 编程 算法

以前端视角,漫谈「云端」

京东科技开发者

云计算 前端 云技术 企业号 3 月 PK 榜

企业号 4 月 PK 榜,火热开启!

InfoQ写作社区官方

热门活动 企业号 4 月 PK 榜

pulsar:创建更多租户 VS 创建更多namespaces

李code

架构 pulsar 调优 业务

Sync包Mutex的原理阐述

Jack

golang

轻松搞懂云成本优化:FinOps,2023年一定要懂的热点趋势!

博文视点Broadview

世界备份日|有“备”而来,才能不为数据安全“蕉绿”

云布道师

存储

易观千帆 | 2023年2月证券APP月活跃用户规模盘点

易观分析

金融 证券 经济

一文读懂mysql锁

Paincupid

MySQL MySQL锁 mysql锁原理 mysql如何上锁 msyql锁分类

碳基大模型--人一生处理多少个token?

FN0

人工智能 AIGC ChatGPT

MobPush 厂商通道SDK集成指南

MobTech袤博科技

从人工智能角度看人肉智能

FN0

AIGC

个人开发者应该如何选购云服务

光毅

重现一条简单SQL的优化过程

GreatSQL

MySQL greatsql greatsql社区

vivo 手机云服务建设之路-平台产品系列04

vivo互联网技术

系统设计 稳定性 数据安全 用户数据 手机云服务

IDC报告:安擎AI服务器同比增长29.2%,三行业位居第一

科技热闻

看完这份SpringBoot神级文档,面试真的可以为所欲为

三十而立

Java IT java面试

Activity初窥门径

二哈侠

android App Activity

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