您的位置:首页 > 财经 > 金融 > Ehcache 笔记

Ehcache 笔记

2024/10/5 13:55:56 来源:https://blog.csdn.net/gaxing4615/article/details/139343178  浏览:    关键词:Ehcache 笔记

前言

说道缓存,大家想到的是一定是Redis,确实在国内Redis被大量应用,推上了新的高度!但是不一定所有的场合都要使用Redis,例如服务器资源紧缺,集成不方便的时候就可以考虑使用本地缓存

简介

缓存应该是每个系统都要考虑的架构,缓存不仅可以加速系统的访问速度还可以提升系统的性能。如我们需要经常访问的高频热点数据,如果把它缓存起来就能有效减少数据库服务器的压力。手机验证码等有一定的失效时间,我们就可以考虑使用缓存,等失效时间过了,就删掉验证码。因此市面上缓存组件也层出不进,常见的有

  • JCache:Java缓存API。由JSR107定义,定义了5个核心接口,分别是CachingProvider,CacheManager,Cache,Entry和Expriy
  • EhCache:纯Java的进程内缓存框架,jvm虚拟机中缓存、速度快,效率高,是Hibernate中默认的CacheProvider,但是共享缓存与集群分布式应用整合不方便
  • Redis:生态完善,通过socket访问缓存服务,效率上是比EhCache低的,但是在集群模式、分布式应用上就比较成熟,是大型应用首先中间件
  • Caffeine:Caffeine是使用Java8对Guava缓存的重写版本,有人称它为缓存之王

优点

  1. 快速
  2. 简单
  3. 多种缓存策略(设置有效期等)
  4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题
  5. 缓存数据会在虚拟机重启的过程中写入磁盘
  6. 可以通过RMI、可插入API等方式进行分布式缓存
  7. 具有缓存和缓存管理器的侦听接口
  8. 支持多缓存管理器实例,以及一个实例的多个缓存区域
  9. 提供Hibernate的缓存实现

jar

<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
<dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><version>2.10.6</version>
</dependency>

本质

就是简单看下SpringBoot关于缓存处理源码是怎么写的。说到底就是上面所说AOP思想,通过动态代理实现,目标方法让代理对象去调用,调用之前先看下缓存有没有,如果有,则从缓存上获取结果并直接返回。如果缓存中没有则执行目标方法,并把方法执行结果缓存。
CacheManager->Cache->Element

Ehcache.xml

默认会加载calsspath下的ehcache.xml,加载失败会加载Ehcache.jar下的ehcache-failsafe.xml

<cache name="account"eternal="false"diskPersistent="false"maxElementsInMemory="10000"timeToIdleSeconds="120"timeToLiveSeconds="120"memoryStoreEvictionPolicy="LRU"></cache><cache name="smsCache"eternal="false"diskPersistent="false"maxElementsInMemory="1000"timeToIdleSeconds="60"timeToLiveSeconds="600"memoryStoreEvictionPolicy="LRU"></cache><!--
name                            缓存名称
eternal                         true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
timeToIdleSeconds               设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态
timeToLiveSeconds               设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义
maxElementsInMemory             内存中最大缓存对象数;maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行
memoryStoreEvictionPolicy       当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)
maxElementsOnDisk               硬盘中最大缓存对象数,若是0表示无穷大
overflowToDisk                  是否保存到磁盘,当系统宕机时
diskPersistent                  是否缓存虚拟机重启期数据,是否持久化磁盘缓存,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名为cache名称,后缀名为index的文件,这个文件中存放了已经持久化在磁盘中的cache的index,找到后会把cache加载到内存,要想把cache真正持久化到磁盘,写程序时注意执行net.sf.ehcache.Cache.put(Element element)后要调用flush()方法
diskSpoolBufferSizeMB           这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
diskExpiryThreadIntervalSeconds 磁盘失效线程运行时间间隔,默认为120秒
clearOnFlush                    内存数量最大时是否清除
-->

策略

Ehcache 提供了多种缓存策略,可以根据实际需求选择合适的策略。其中,最常用的包括:

  • LRU(Least Recently Used):移除最近最少使用的缓存项。(时间)
  • LFU(Least Frequently Used):移除最不经常使用的缓存项。(次数)
  • FIFO(First In, First Out):先进先出,即移除最早加入的缓存项。
  • TTL(Time To Live):根据缓存项的过期时间来判断是否要移除该项。
    随机替换:随机选择一项进行移除。

缓存注解-自动

JCache(JSR-107)的注解去大大简化我们的开发。

相关注解和概念说明
Cache缓存接口,定义缓存操作。实现有:RedistCache、EhCacheCache、ConcurrentMapCache等
CacheManager缓存管理器,管理各种缓存(Cache)组件
@Cacheable主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@CacheEvict清空缓存
@CachePut保证方法被调用,又希望结果被缓存
@EnableCaching开启基于注解的缓存
keyGenerator缓存数据时key生成策略
serialize缓存数据时value序列化策略

JSR-107缓存注解使用

光知道SpringBoot集成Ehcache还不够,我们还要知道怎么使用。然而ehcache在实际应用中可以抽离出来单独使用,但是需要自己手动实例化与put数据,一般不推荐。推荐配合JSR-107缓存注解去使用(因为Spring都给我们封装好了),Spring的缓存功能丰富,它还提供了很多注解,去完成不同的场景~其中使用最多的是@Cacheable注解。

@Cacheable (使用最多)
/* 
@Cacheable几个属性:1.cacheNames/value:缓存组件的名字 2.key:指定缓存数据使用的key,默认使用方法参数的值,可以编写SpEL进行指定,如#id就是参数的值3.keyGenerator:key的生成器,可以自己指定key的生成器的组件id,使用时key/keyGenerator只能二选一4.cacheManager:指定缓存管理器,或者cacheResolver指定获取解析器5.condition:指定复合条件的情况下才缓存,如condition = "#id > 0"6.unless:否定缓存,当unless指定的条件为true,方法的返回值就不会被缓存,如 unless = "#result == null"7.sync:是否启用异步模式,如果启用unless就不支持了。默认为false8.缓存的值就是方法返回的结果
*/
// 使用示例@Override@Cacheable(value = "account",key = "#id")public Account getAccountById(int id) {final Account account = accountDao.selectById(id);return Objects.requireNonNull(account);}
@CachePut

即调用方法,又更新缓存数据。如修改了某个数据库的某个数据,同时更新缓存
执行过程:

  1. 先调用目标方法
  2. 将目标方法的结果缓存起来
    value:命名空间
    key: 主键
    @CachePut(value = "account",key = "#id")public Account getAccountById(int id) {final Account account = accountDao.selectById(id);return Objects.requireNonNull(account);}
@CacheEvict

缓存清除,一般在删除数据方法中使用

    @CacheEvict(value = "account",key = "#id")public boolean deleteAccountById(int id) {return accountDao.deleteById(id) > 0;}

CacheManager-手动

getCache
put
get
remove

 @Autowiredprivate CacheManager cacheManager;@Overridepublic String sendSms(String phoneNumber) {final String uuid = UUID.randomUUID().toString().substring(0, 4);cacheManager.getCache("smsCache").put(new Element(phoneNumber, uuid));return uuid;}@Overridepublic boolean checkSms(String phoneNumber, String code) {final Cache smsCache = cacheManager.getCache("smsCache");smsCache.final Element element = smsCache.get(phoneNumber);final String smscode = (String) element.getObjectValue();return code.equals(smscode);}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com