eureka缓存细节以及生产环境的最佳配置

eureka作为spring cloud微服务架构里的注册中心,是非常核心的一个组件。它本身的架构避免了复杂的选主算法,比较简单,搭个demo也确实很快,但是如果要用于生产环境,还是得注意很多东西,尤其是下线延迟...

一、服务获取中的缓存问题

第一节的内容都是从这个issue翻译的:Documentation: changing Eureka renewal frequency WILL break the self-preservation feature of the server

1.1 为什么修改client的默认心跳时间,会导致自我保护模式失效?

Eureka Service会认为客户端是以30s的频率来发送心跳的。服务端期望收到的最大心跳时间是:

n instances x 2(60s/30s) x threshold

如果是2个实例,Eureka会期望每分钟有:2 instances x 2 x 85% =3.4个心跳,也就是说需要3个心跳。
如果client的心跳改成15s,挂掉一个,另一个在1min内会发出4个心跳,而这时候的阈值还是3.4个,自我保护模式就失效了。
核心原因就是在Eureka Server计算期望心跳数的时候写死了每分钟的心跳间隔,即30秒,所以他永远会是*2(感觉像是新手写的代码啊啊啊 -_-)

image

还有一个参数可以调整,eureka.server.renewalThresholdUpdateIntervalMs,心跳阈值重新计算的周期,默认15分钟,可以改短一点,2min

1.2 客户端首次注册时间为什么要30s?如何改进?

首次注册行为是和首次心跳绑定在一起的,首次心跳发送以后会收到not found的响应,client就知道还没注册过,client就会马上注册。首次心跳由参数

eureka.instance.leaseRenewalIntervalInSeconds控制的,默认30

可以通过eureka.client.initialInstanceInfoReplicationIntervalSeconds参数来加快首次注册的速度。他是控制首次改变实例状态(UP/DOWN )的时间,启动的时候状态肯定是需要改变的,所以他可以用来加快首次注册速度,并且改变这个值不会影响到保护模式

另外如果你使用的是spring cloud eureka的话没首次注册延迟的问题,他会马上注册

1.3 其他影响快速获取服务信息的因素

【服务端缓存】
因为服务端默认会有个read only response cache(下面会细说),每30秒更新一次(eureka.server.response-cache-update-interval-ms),所以可能注册了不是马上能看到(虽然通过rest api不能看到,但是你可以在web ui上看到,因为ui没有缓存)

【客户端缓存】
Eureka Client缓存的定期更新周期,他由eureka.client.registryFetchIntervalSeconds控制,默认30秒, 改成5秒

【Ribbon缓存】
如果你采用Ribbon来访问服务,那么这里会有个缓存(他的数据来源是本地Eureka Client缓存),他由ribbon. ServerListRefreshInterval控制,默认30秒, 改成2秒

1.4 怎么更快的踢掉没有心跳的机器

eureka.instance.leaseExpirationDurationInSeconds,这个值用来控制多久踢掉机器,默认是3个心跳周期,有点久,可以考虑改成2个,他不会影响到保护模式(如果开启自我保护模式,心跳间隔因为1.1的bug不能改,只能改这个了 -_-)


二、服务端缓存细节

Eureka内部的缓存分很多级,主要有registry、readWriterCacheMap、readOnlyCacheMap;另外还有一个维护最近180s增量的队列recentlyChangedQueue

2.1 写操作

包括注册、取消注册等,都直接操作在registry上,同时也会更新recentlyChangedQueue和readWriterCacheMap

2.2 读操作

读默认是从readOnlyCacheMap读取,读不到的话再从readWriterCacheMap,还是没有再从registry

2.3 滥用缓存的读操作

这个读操作的三级缓存结构,非常让人困惑,registry已经是ConcurrentHashMap,纯内存操作,性能非常高了,为什么前面还要加两级缓存;readWriterCacheMap的数据是在写入以后responseCacheAutoExpirationInSeconds(默认180)秒内失效,readOnlyCacheMap则是一个定时任务,每responseCacheUpdateIntervalMs(默认30)秒从readWriterCacheMap获取最新数据

2.4 去掉readOnlyCacheMap

从CAP理论上看,Eureka是一个AP系统,但是在C层面这么弱,就是因为各种无谓的缓存造成的,看了下readWriterCacheMap去掉比较难,但是readOnlyCacheMap有一个开关useReadOnlyResponseCache,果断关掉!!


三、Time Lag

最后再来看下Eureka wiki中提到的2min time lag问题,其实分多个角度看,不一定是2min

3.1 服务正常上线/修改,最大可能会有120s滞后

1.直接使用Eureka:30(首次注册 init registe) + 30(readOnlyCacheMap)+30(client fetch interval)+30(ribbon cache)=120
2.在Spring Cloud环境下使用这些组件(Eureka, Ribbon):不会有首次注册30秒延迟的问题,服务启动后会马上注册,所以从注册到发现,最多可能是90s。

服务异常下线:最大可能会有270s滞后

1.定时清理任务每eureka.server. evictionIntervalTimerInMs(默认60)执行一次清理任务
2.每次清理任务会把90秒(3个心跳周期,eureka.instance.leaseExpirationDurationInSeconds)没收到心跳的踢除,但是根据官方的说法 ,因为代码实现的bug,这个时间其实是两倍,即180秒,也就是说如果一个客户端因为网络问题或者主机问题异常下线,可能会在180秒后才剔除
3.读取端,因为readOnlyCacheMap以及客户端缓存的存在,可能会在30(readOnlyCacheMap)+30(client fetch interval)+30(ribbon)=90

  1. 所以极端情况最终可能会是180+90=270

四、生产环境最佳配置

总结前面3点,经过梳理后,推荐的生产环境最佳配置如下:(可用于中小规模环境):

Eureka Server端配置

## 中小规模下,自我保护模式坑比好处多,所以关闭它
eureka.server.enableSelfPreservation=false
## 心跳阈值计算周期,如果开启自我保护模式,可以改一下这个配置
## eureka.server.renewalThresholdUpdateIntervalMs=120000

## 主动失效检测间隔,配置成5秒
eureka.server.evictionIntervalTimerInMs=5000

## 心跳间隔,5秒
eureka.instance.leaseRenewalIntervalInSeconds=5
## 没有心跳的淘汰时间,10秒
eureka.instance.leaseExpirationDurationInSeconds=10

## 禁用readOnlyCacheMap
eureka.server. useReadOnlyResponseCache=false

服务提供者和clinet配置

## 心跳间隔,5秒
eureka.instance.leaseRenewalIntervalInSeconds=5
## 没有心跳的淘汰时间,10秒
eureka.instance.leaseExpirationDurationInSeconds=10

# 定时刷新本地缓存时间
eureka.client.registryFetchIntervalSeconds=5
# ribbon缓存时间
ribbon.ServerListRefreshInterval=2000

改成上面配置后:

  • 正常上线下线客户端最大感知时间:eureka.client.registryFetchIntervalSeconds+ribbon. ServerListRefreshInterval = 7秒

  • 异常下线客户端最大感知时间:
    2*eureka.instance.leaseExpirationDurationInSeconds+
    eureka.server.evictionIntervalTimerInMs+
    eureka.client.registryFetchIntervalSeconds+
    ribbon. ServerListRefreshInterval = 32

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容