本地緩存Ehcache
什麼是Ehcache
Ehcache是純java的開源緩存框架,具有快速、精幹等特點,是Hibernate中默認的CacheProvider。它主要面向通用緩存、Java EE和輕量級容器,具有內存和磁盤存儲、緩存加載器、緩存擴展、緩存異常處理程序。
Ehcache最初由Greg Luck於2003年開始開發。2009年,該項目被Terracotta購買。軟件仍然開源,但一些新的主要功能(例如,快速可重啓性之間的一致性的)只能在商業產品中使用。
Ehcache 被廣泛用於在Hibernate、Spring、Cocoon等其他開源系統。
Ehcache的主要特性
1.快速;
2.簡單;
3.多種緩存策略;
4.緩存數據有兩級:內存和磁盤,因此無需擔心容量問題;
5.緩存數據會在虛擬機重啓的過程中寫入磁盤;
6.可以通過 RMI、可插入 API 等方式進行分佈式緩存;
7.具有緩存和緩存管理器的偵聽接口;
8.支持多緩存管理器實例,以及一個實例的多個緩存區域;
9.提供 Hibernate 的緩存實現;
Ehcache使用介紹
Ehcache是用來管理緩存的一個工具,其緩存的數據可以是存放在內存裏面的,也可以是存放在硬盤上的。其核心是CacheManager,一切Ehcache的應用都是從CacheManager開始的。它是用來管理Cache(緩存)的,一個應用可以有多個CacheManager,而一個CacheManager下又可以有多個Cache。Cache內部保存的是一個個的Element,而一個Element中保存的是一個key和value的配對,相當於Map裏面的一個Entry。
Ehcache緩存過期策略
當緩存需要被清理時(比如空間佔用已經接近臨界值了),需要使用某種淘汰算法來決定清理掉哪些數據。常用的淘汰算法有下面幾種:
FIFO:First In First Out,先進先出。判斷被存儲的時間,離目前最遠的數據優先被淘汰。
LRU:Least Recently Used,最近最少使用。判斷最近被使用的時間,目前最遠的數據優先被淘汰。
LFU:Least Frequently Used,最不經常使用。在一段時間內,數據被使用次數最少的,優先被淘汰。
Maven環境依賴
<!--開啓 cache 緩存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- ehcache緩存 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
</dependency>
YML配置文件信息
spring:
cache:
type: ehcache
ehcache:
config: classpath:ehcache-local.xml
EhCache配置
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="defaultCache">
<diskStore path="java.io.tmpdir/Java_paper_tmp/ehcache" />
<!-- defaultCache,是默認的緩存策略 -->
<!-- 如果你指定的緩存策略沒有找到,那麼就用這個默認的緩存策略 -->
<!-- external:如果設置爲true的話,那麼timeout就沒有效果,緩存就會一直存在,一般默認就是false -->
<!-- maxElementsInMemory:內存中可以緩存多少個緩存條目,在實踐中,你是需要自己去計算的,比如你計算你要緩存的對象是什麼?有多大?最多可以緩存多少MB,或者多少個G的數據?除以每個對象的大小,計算出最多可以放多少個對象 -->
<!-- overflowToDisk:如果內存不夠的時候,是否溢出到磁盤 -->
<!-- diskPersistent:是否啓用磁盤持久化的機制,在jvm崩潰的時候和重啓之間,不用 -->
<!-- timeToIdleSeconds:對象最大的閒置的時間,如果超出閒置的時間,可能就會過期,我們這裏就不用了,緩存最多閒置5分鐘就被幹掉了 -->
<!-- timeToLiveSeconds:對象最多存活的時間,我們這裏也不用,超過這個時間,緩存就過期,就沒了 -->
<!-- memoryStoreEvictionPolicy:當緩存數量達到了最大的指定條目數的時候,需要採用一定的算法,從緩存中清除一批數據,LRU,最近最少使用算法,最近一段時間內,最少使用的那些數據,就被幹掉了 -->
<defaultCache maxElementsInMemory="1000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
diskPersistent="true" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
<!-- 手動指定的緩存策略 -->
<!-- 比如你一個應用吧,可能要緩存很多種不同的數據,比如說商品信息,或者是其他的一些數據 -->
<!-- 對不同的數據,緩存策略可以在這裏配置多種 -->
<!-- 系統緩存 -->
<!--
Ehcache 使用Map集合實現的 element 其實就是 key 和value
一、以下屬性是必須的:
1、name: Cache的名稱,必須是唯一的(ehcache會把這個cache放到HashMap裏)。
2、maxElementsInMemory:在內存中緩存的element的最大數目。
3、maxElementsOnDisk:在磁盤上緩存的element的最大數目,默認值爲0,表示不限制。
4、eternal:設定緩存的elements是否永遠不過期。如果爲true,則緩存的數據始終有效,如果爲false那麼還要根據timeToIdleSeconds,timeToLiveSeconds判斷。
5、overflowToDisk: 如果內存中數據超過內存限制,是否要緩存到磁盤上。
二、以下屬性是可選的:
1、timeToIdleSeconds: 對象空閒時間,指對象在多長時間沒有被訪問就會失效。只對eternal爲false的有效。默認值0,表示一直可以訪問。
2、timeToLiveSeconds: 對象存活時間,指對象從創建到失效所需要的時間。只對eternal爲false的有效。默認值0,表示一直可以訪問。
3、diskPersistent: 是否在磁盤上持久化。指重啓jvm後,數據是否有效。默認爲false。
4、diskExpiryThreadIntervalSeconds: 對象檢測線程運行時間間隔。標識對象狀態的線程多長時間運行一次。
5、diskSpoolBufferSizeMB: DiskStore使用的磁盤大小,默認值30MB。每個cache使用各自的DiskStore。
6、memoryStoreEvictionPolicy: 如果內存中數據超過內存限制,向磁盤緩存時的策略。默認值LRU,可選FIFO、LFU。
-->
<cache name="dbFormCache" maxEntriesLocalHeap="100" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120"
diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
overflowToDisk="true"/>
</ehcache>
啓動類方式@EnableCaching
@SpringBootApplication
@EnableTransactionManagement
@ServletComponentScan
@MapperScan("com.jetsen.edu.dao")
@ImportResource(locations = {"classpath:druid-bean.xml"})
@EnableCaching
public class EduCloudServicePaperApplication
@CachePut(key="'dbFrom_'+#dbCacheForm.bizKey", value="dbFormCache")
@Transactional(readOnly = false)
public void updateDbCacheByBizKey(DbCacheForm dbCacheForm) {
dbCacheForm.setUpdateDate(DateUtils.now());
//修改信息
dbCacheFormDao.updateDbCacheByBizKey(dbCacheForm);
}
@Cacheable(key="'dbFrom_'+#bizKey",value="dbFormCache")
public DbCacheForm findDbCacheByBizKey(String bizKey) {
DbCacheForm dbCacheForm = new DbCacheForm();
dbCacheForm.setBizKey(bizKey);
return dbCacheFormDao.findDbCacheByBizKey(dbCacheForm);
}
/**
* 刪除
*/
@CacheEvict(key="'dbFrom_'+#dbCacheForm.bizKey", value="dbFormCache")
@Transactional(readOnly=false)
public Object delete(DbCacheForm dbCacheForm) {
dbCacheFormDao.delete(dbCacheForm);
return ReturnMsgUtils.returnMsg(CODE_200, null, MSG_SUCCESS);
}
當然業務如有需要清除所有Ehcache緩存,可以注入CacheManager進行刪除
cacheManager.getCache("dbFormCache").clear();