2024年9月eureka 三级缓存 作用(三级缓存java)

 更新时间:2024-09-21 09:42:47

  ⑴eureka三级缓存作用(三级缓存java)

  ⑵本文主要介绍尤里卡三级缓存功能(三级缓存java),下面一起看看尤里卡三级缓存功能(三级缓存java)相关资讯。

  ⑶为了提供响应效率,EurekaServer提供了两层缓存结构,将Eureka客户端所需的注册信息直接存储在缓存结构中。实现原理如下图所示。

  ⑷第一层缓存:readOnlyCacheMap,本质上是ConcurrentHashMap,依靠计时来同步readWriteCacheMap中的数据,默认时间是秒。

  ⑸ReadOnlyCacheMap:是一个CurrentHashMap只读缓存,主要用于客户端获取注册信息。它的缓存更新依赖于定时器的更新。通过与读写缓存的值比较,如果数据不一致,以读写缓存的数据为准。

  ⑹第二层缓存:读写缓存,本质上是番石榴缓存。

  ⑺读写缓存:读写缓存的数据主要与存储层同步。当获得缓存时,判断缓存中是否没有数据。如果没有数据,则通过CacheLoader的load方法加载,加载成功后将数据放入缓存,同时返回数据。

  ⑻默认情况下,读写缓存映射缓存的过期时间为秒。当服务离线、过期、注册或更改时,此缓存中的数据将被清除。

  ⑼当Eureka客户端获取完整或增量数据时,会先从一级缓存中获取;如果一级缓存中不存在,则从二级缓存中获取;如果二级缓存没有。;t存在,此时先将存储层的数据同步到缓存中,再从缓存中获取。

  ⑽通过EurekaServer的两层缓存机制,可以非常有效地提高EurekaServer的响应时间,并通过数据存储层和缓存层的数据切割,根据使用场景提供不同的数据支持。

  ⑾多级缓存的意义#这里为什么要设计多级缓存?原因很简单,就是当有大规模的服务注册和更新时,如果只修改一个ConcurrentHashMap数据,那么锁的存在必然会导致竞争,影响性能。

  ⑿Eureka是AP机型,只需要满足最终供货即可。所以这里使用多级缓存来实现读写分离。注册方法写的时候直接写内存注册表,写完表后主动使读写缓存失效。

  ⒀获取注册信息的接口首先从只读缓存中获取信息,但只读缓存不从只读缓存中获取信息。;t从读写缓存中获取,而读写缓存没有不要从内存注册表中获取它(不只是获取它,它这里就比较复杂了)。和读写缓存更新回写只读缓存。

  ⒁responsepacheupdateintervals:readonlycach:读写缓存映射缓存过期,默认值为秒。缓存初始化#readWriteCacheMap使用LoadingCache对象,这是guava中提供的实现内存缓存的api。创建如下

  ⒂Loadingcachelong,StringCache=CacheBuilder。newbuilder//缓存池大小,当缓存项接近这个大小时,Guava开始回收旧的缓存项。maximumSize()//如果时间对象没有被读/写,将会从内存中删除(在另一个线程中不定期维护)。ExpireAfterAess(,时间单位。分钟)//删除侦听器。当缓存项被移除时,将会触发。removallistener(NewremovallistenerLong,String{OverridePublicVoidonremovalLong,Stringrn){//执行逻辑运算}})。recordStats//开启番石榴缓存的统计功能。Build(newcacheloaderstring,object{overridepublicobjectload(stringkey){//GetobjectsfromSQL或noSQL}});CacheLoader类用于自动加载缓存。当方法ReadWriteCache。Get(key)被触发,CacheLoader.load方法将被回调,根据key在服务注册信息中搜索实例数据进行缓存。

  ⒃ResponseCacheImpl(EurekaServerConfig服务器配置,服务器编解码器服务器编解码器,AbstractInstanceRegistry注册表){this.serverConfig=serverConfigthis.servercodecs=servercodecs;this.shouldusereadonlyresponsecache=serverconfig.shouldusereadonlyresponsecache;this.registry=registrylongresponseCacheUpdateIntervalMs=serverconfig.getresponsecacheupdateintervalms;this.readwritecachemap=cachebuilder.newbuilder。initialcapacity(serverconfig.getinitialcapacityofresponsecache)。expireAfterWrite(serverconfig.getresponsecacheautoexpirationseconds,TimeUnit。秒)。removallistener(newremovallistenerKey,Value{Overridepublicvoidonremove(removalnotificationKey,Valuenotification){KeyremovedKey=notification.getkey;if(removedKey.hasregions){KeycloneWithNoRegions=removedKey.clonewithoutregions;regionspecifickeys.remove(cloneWithNoRegions,removedkey);}}}).build(newCacheLoaderKey,Value{OverridepublicValueload(KeyKey)抛出异常{if(Key.hasregions){KeycloneWithNoRegions=Key.clonewithoutregions;regionspecifickeys.put(cloneWithNoRegions,key);}ValueValue=generatePayload(key);//注意这里的返回值;}});缓存的加载基于generatePayload方法,代码如下。

  ⒄私有值generatePayload(KeyKey){Stopwatchtracer=null;尝试{String有效负载;switch(key.getentitytype){caseApplication:布尔isremoteregionrequested=key.hasregions;if(ALL_apps.equals(key.getname){if(isremotegionrequested){tracer=serializallappswarmotegiontimer.start;payload=getPayLoad(key,registry.getapplicationsfromregions(key.getregions));}else{tracer=serializallapptimer.start;payload=getPayLoad(key,registry.getapplications);}}elseif(ALL_APPS_delta.equals(key.getname){if(isremoteregionrequested){tracer=serializedeltappswithoremotegiontimer.start;versiondeltawithregions.incrementandget;versiondeltawithregionslegcy.incrementandget;payload=getPayLoad(key,registry.getapplicationdeltasfromultipleregions(key.getregions));}else{tracer=serializedeltappstimer.start;versiondelta.incrementandget;versiondeltagcy.incrementandget;payload=getPayLoad(key,registry.getapplicationdeltas);}}else{tracer=serializeoneapptimer.start;payload=getPayLoad(key,registry.getapplication(k:案例SVIP:tracer=serializeptimer.start;payload=getPayLoad(key,getApplicationsForVip(k:登录器。错误("在缓存键中找到了未识别的实体typ:{}。",key.getentitytype);有效载荷=""打破;}返回新值(有效载荷);}最后{if(tracer!=null){tracer.stop;}}}此方法接受一个键类型的参数,并返回一个值类型。重要领域中的关键是:

  ⒅表示有效负载文本格式的KeyType有JSON和XML值。指示缓存类型的EntityType有三个值:应用程序、VIP和SVIP。EntityName,表示缓存的名称,可以是单个应用程序名称,也可以是ALL_APPS或ALL_APPS_DELTA。值有一个String类型的有效负载和一个字节数组,表示gzip的压缩字节。

  ⒆缓存同步#在ResponseCacheImpl的构造和实现中,初始化一个定时任务,每个定时任务

  ⒇ResponseCacheImpl(EurekaServerConfig服务器配置,服务器编解码器服务器编解码器,抽象stanceregistry注册表){//省略...if(shouldusereadedonlyresponseseache){timer。schedule(getcacheupdatetask,newDate((system.currenttimemillis/responseCacheUpdateIntervalMs)*responseCacheUpdateIntervalMs)responseCacheUpdateIntervalMs),responseCacheUpdateIntervalMs);}}默认情况下,有差异的数据每秒从读写缓存更新到readOnlyCacheMap。

  ⒈privateTimerTaskgetCacheUpdateTask{returnnewTimerTask{Overridepublicvoidrun{logg:readonlycach:{}{}{}{}"、key.getEntityType、key.getName、key.getVersion、key.gettype;}请尝试{currentrequestversion.set(key.getversion);valuecachevalue=readwritecachemap.get(key);valuecurrentcachevalue=readonlycachemap.get(key);if(cacheValue!=currentCacheValue){//判断差异信息,如有差异。更新readonlycachemap.put(key,cachevalue);}}catch(Throwableth){logger.error("从关键字{}的响应缓存更新客户端缓存时出错,key.toStringpact,th);}finally{currentrequestversion.remove;}}}};}缓存失效#在这个方法中,保存服务信息时,会调用失效缓存失效缓存。

  ⒉publicvoidregister(instanceinforegister,intleaseDuration,booleanisReplication){//....invalidatecache(register.getappname、register.getvipaddress、register.getsecurevipaddress);//...}最后调用ResponseCach:键){logg:{}{}{}{},{}"、key.getEntityType、key.getName、key.getVersion、key.getType、key.geteurekaaept;readwritecachemap.invalidate(key);collectionkeykeysWithRegions=regionspecifick:k:{}{}{}{}{}"、key.getEntityType、key.getName、key.getVersion、key.getType、key.geteurekaaept;readwritecachemap.invalidate(keysWithRegion);}}}}版权声明:本博客所有文章,除特别注明外,均采用BY-NC-SA.许可协议。转载请注明来自Mic的架构!如果这篇文章对你有帮助,请给我一些关注和好评。你的坚持是我不断创作的动力。欢迎关注"跟随麦克风学习架构及并在官方账号,官方账号获取更多技术干货!

您可能感兴趣的文章:

相关文章