在互聯網應用中,由於併發量比傳統的企業級應用會高出很多,所以處理大併發的問題就顯得尤爲重要。在硬件資源一定的情況下,在軟件層面上解決高併發問題會比較經濟實惠一些。解決併發的根本在於提高系統的響應時間與單位時間的吞吐量。解決問題的思路可分兩個維度,一是提高系統的單位時間內的運算效率(比如集羣),二是減少系統不必要的開支(比如緩存)。緩存又會分爲客戶端緩存與服務器端緩存。
我現在做的項目springMVC web 主要爲客戶端提供接口,由於複雜的多表鏈接查詢,每次加載多少2-4秒,讓客戶端很慢,近期學習了Ehcache 緩存,讓項目得到了很大的優化。
第一步 下載相應jar包,加載到項目裏。
ehcache-core-2.4.3.jar (主程序)
ehcache-spring-annotations-1.2.0.jar
(註解)
slf4j-api-1.6.6.jar(依賴)
第二步 修改配置文件
1.spring-content.xml
<!-- 緩存配置 -->
<!-- 啓用緩存註解功能(請將其配置在Spring主配置文件中) -->
<cache:annotation-driven cache-manager="cacheManager" />
<!-- Spring自己的基於java.util.concurrent.ConcurrentHashMap實現的緩存管理器(該功能是從Spring3.1開始提供的) -->
<!-- 若只想使用Spring自身提供的緩存器,則註釋掉下面的兩個關於Ehcache配置的bean,並啓用上面的SimpleCacheManager即可 -->
<!-- Spring提供的基於的Ehcache實現的緩存管理器 -->
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="cacheManagerFactory" />
</bean>
2.新建ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
<diskStore path="d:/cache" />
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="600"
overflowToDisk="false"/>
<cache name="talkCache"
maxElementsOnDisk="20000"
maxElementsInMemory="2000"
eternal="false"
overflowToDisk="true"
timeToLiveSeconds="600"
diskPersistent="true"/>
<cache name="topicCache" eternal="false"
maxElementsOnDisk="20000"
maxElementsInMemory="2000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="600" />
</ehcache>
參數說明:
<diskStore>==========當內存緩存中對象數量超過maxElementsInMemory時,將緩存對象寫到磁盤緩存中(需對象實現序列化接口)
<diskStore path="">==用來配置磁盤緩存使用的物理路徑,Ehcache磁盤緩存使用的文件後綴名是*.data和*.index
name=================緩存名稱,cache的唯一標識(ehcache會把這個cache放到HashMap裏)
maxElementsOnDisk====磁盤緩存中最多可以存放的元素數量,0表示無窮大
maxElementsInMemory==內存緩存中最多可以存放的元素數量,若放入Cache中的元素超過這個數值,則有以下兩種情況
1)若overflowToDisk=true,則會將Cache中多出的元素放入磁盤文件中
2)若overflowToDisk=false,則根據memoryStoreEvictionPolicy策略替換Cache中原有的元素
eternal==============緩存中對象是否永久有效,即是否永駐內存,true時將忽略timeToIdleSeconds和timeToLiveSeconds
timeToIdleSeconds====緩存數據在失效前的允許閒置時間(單位:秒),僅當eternal=false時使用,默認值是0表示可閒置時間無窮大,此爲可選屬性即訪問這個cache中元素的最大間隔時間,若超過這個時間沒有訪問此Cache中的某個元素,那麼此元素將被從Cache中清除
timeToLiveSeconds====緩存數據在失效前的允許存活時間(單位:秒),僅當eternal=false時使用,默認值是0表示可存活時間無窮大即Cache中的某元素從創建到清楚的生存時間,也就是說從創建開始計時,當超過這個時間時,此元素將從Cache中清除
overflowToDisk=======內存不足時,是否啓用磁盤緩存(即內存中對象數量達到maxElementsInMemory時,Ehcache會將對象寫到磁盤中) 會根據標籤中path值查找對應的屬性值,寫入磁盤的文件會放在path文件夾下,文件的名稱是cache的名稱,後綴名是data
diskPersistent=======是否持久化磁盤緩存,當這個屬性的值爲true時,系統在初始化時會在磁盤中查找文件名爲cache名稱,後綴名爲index的文件,這個文件中存放了已經持久化在磁盤中的cache的index,找到後會把cache加載到內存, 要想把cache真正持久化到磁盤,寫程序時注意執行net.sf.ehcache.Cache.put(Element element)後要調用flush()方法
diskExpiryThreadIntervalSeconds==磁盤緩存的清理線程運行間隔,默認是120秒
diskSpoolBufferSizeMB============設置DiskStore(磁盤緩存)的緩存區大小,默認是30MB
memoryStoreEvictionPolicy========內存存儲與釋放策略,即達到maxElementsInMemory限制時,Ehcache會根據指定策略清理內存共有三種策略,分別爲LRU(最近最少使用)、LFU(最常用的)、FIFO(先進先出)
第三步 設置實現層緩存註解、
1.在業務層 service 的方法中做一下:
<strong>@Cacheable(value = "talkCache")</strong>
public DRFResultBean talkMothod(String argJson,String method,String pageJson){
return talkDao.talkMothod(argJson, method,pageJson);
}
@Cacheable(cacheName="baseCache")
這個註解就是做到緩存數據,cacheName對應ehcache.xml 中配置
2.在數據訪問層Dao的方法上增加:
@TriggersRemove(cacheName="talkCache",removeAll=true)
public DRFResultBean talkMothod(String argJson,String method,String pageJson){
String dbid = constantUtil.getPropertiesByName("qx");
String resultJson = ((com.gnet.webService.drf.IDRFService) BeanUtil
.getBean("drfWebService")).executeFunction(dbid, method, argJson, pageJson);
DRFResultBean resultBean = (DRFResultBean) JSONObject.parseObject(resultJson, DRFResultBean.class);
return resultBean;
}
@TriggersRemove(cacheName="baseCache",removeAll=true)
這個註解的作用就是當數據發生變化的時候清除緩存,做到數據同步
第四步 訪問調用相應鏈接,第一次調用原方法,3秒,第二次再調用,元數據未修改,程序直接走緩存。