本文主要是介绍spring boot和缓存(尤其是堆内缓存)结合使用,如何解决缓存的雪崩问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
以ehcache为例
spring boot和ehcache结合后,ehcache的配置文件是写死超时时间的。
举例如下:
<diskStore path="/tmp/dcep"/><cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,
multicastGroupPort=4446, timeToLive=1"/><cacheManagerPeerListenerFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"properties="socketTimeoutMillis=2000"/><cache name="properties"maxBytesLocalHeap="100M" eternal="false" overflowToDisk="false"timeToLiveSeconds="100000"copyOnRead="true"copyOnWrite="true"><!-- 以下配置ehcache cluster,集群具有逐出、互相通信等功能,仅能做有限的分布式一致性,作为一级缓存,不建议配置集群功能,ehcache 不建议使用在对一致性要求高的地方 -->
<!-- <cacheEventListenerFactory -->
<!-- class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" -->
<!-- properties="replicateAsynchronously=false, -->
<!-- replicatePuts=false, -->
<!-- replicateUpdates=false, -->
<!-- replicateUpdatesViaCopy=false, -->
<!-- replicateRemovals=true "/> --></cache>
文中timeToLiveSeconds就是超时时间。代码中都配置使用这个properties的cache的时候,就会同时在timeToLiveSeconds后失效,同时访问数据库,造成缓存雪崩。
解决方案:
@Beanpublic CacheManagerCustomizers cacheManagerCustomizers(EhCachePropertiesConfig ehCachePropertiesConfig) {return new CacheManagerCustomizers(Arrays.asList(ehCacheCacheManager->{if(ehCacheCacheManager instanceof EhCacheCacheManager){net.sf.ehcache.CacheManager nativeEhCacheManager = ((EhCacheCacheManager)ehCacheCacheManager).getCacheManager();ehCachePropertiesConfig.reSetConfig(nativeEhCacheManager);}}));}
生成一个CacheManagerCustomizers的bean。spring boot会判断该bean是否存在,如果存在,则使用用户生成的这个bean。
在生成ehcachecachemanager后,可以通过这个bean对cache进行修改。在上面代码中,通过这个类,对ehcachecachemanager进行cache配置的修改。
resetconfig代码如下:
@Component
public class EhCachePropertiesReset implements EhCachePropertiesConfig {//向上波动最大值int maxVariation = 10;Random rand = new Random();@Overridepublic void reSetConfig(CacheManager cacheManager) {// TODO Auto-generated method stubMap<String, CacheConfiguration> configByCacheName = cacheManager.getConfiguration().getCacheConfigurations();configByCacheName.forEach((k,v)->{long timeToLiveSeconds = v.getTimeToLiveSeconds();if(timeToLiveSeconds != 0){int variation = rand.ints(0, maxVariation).findFirst().orElse(0);long newTimeLiveSeconds = timeToLiveSeconds + variation;v.setTimeToLiveSeconds(newTimeLiveSeconds);//这一步真正设置每一个cache的过期时间cacheManager.getCache(k).getCacheConfiguration().setTimeToLiveSeconds(newTimeLiveSeconds);}}); }
}
通过随机化方法,对在配置文件中配置的数值进行随机化扰动。
这篇关于spring boot和缓存(尤其是堆内缓存)结合使用,如何解决缓存的雪崩问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!