Java緩衝組件 EhCache 入門教程

來源:互聯網
上載者:User

標籤:爬蟲   範圍   imp   err   包名   default   輕量   作用   web.xml   

1.技術背景:

    系統緩衝是位於應用程式與物理資料來源之間,用於臨時存放複製資料的記憶體地區,目的是為減少應用程式對物理資料來源訪問的次數,從而提高應用程式的運行效能。緩衝設想記憶體是有限的,緩衝的時效性也是有限的,所以可以設定記憶體數量的大小可以執行失效演算法,可以在記憶體滿了的情況下,按照最少訪問等演算法將緩衝直接移除或切換到硬碟上。

    Ehcache從Hibernate發展而來,逐漸涵蓋了Cache界的全部功能,是目前發展勢頭最好的一個項目,具有快速、簡單、低消耗、擴充性強、支援對象或序列化緩衝,支援緩衝或元素的失效,提供LRU、LFU和FIFO緩衝策略,支援記憶體緩衝和硬碟緩衝和分布式緩衝機制等特點。其中Cache的儲存方式為記憶體或磁碟(ps:無須擔心容量問題)

2.EhCahe的類層次介紹:

    主要分為三層,最上層是CacheManager,它是操作Ehcache的入口。可以通過CacheManager.getInstance()獲得一個單子的CacheManager,或者通過CacheManager的建構函式建立一個新的CacheManager。每個CacheManger都管理多個Cache。每個Cache都以一種類Hash的方式,關聯多個Element。Element就是我們用於存放緩衝內容的地方。

3.環境搭建:

    很簡單只需要將ehcache-2.1.0-distribution.tar.gz和ehcache-web-2.0.2-distribution.tar.gz擠壓的jar包放入WEB-INF/lib下。

    再建立一個重要的設定檔ehcache.xml,可以從ehcache組件包中拷貝一個,也可以自己建立一個,需要放到classpath下,一般放於/WEB-INF/classed/ehcache.xml;具體的設定檔可以網上搜一下

4.實際運用

    一個網站的首頁估計是被訪問次數最多的,我們可以考慮給首頁做一個頁面緩衝;

    緩衝策略:應該是某個固定時間之內不變的,比如說2分鐘更新一次,以應用結構page-filter-action-service-dao-db為例。

    位置:頁面緩衝做到盡量靠近客戶的地方,就是在page和filter之間,這樣的優點就是第一個使用者請求後,頁面被緩衝,第二個使用者在請求,走到filter這個請求就結束了,需要在走到action-service-dao-db,好處當然是伺服器壓力大大降低和用戶端頁面響應速度加快。

    首頁頁面緩衝存活時間定為2分鐘,也就是參數timeToLiveSeconds(緩衝的存活時間)應該設定為120,同時timeToIdleSeconds(多長時間不訪問緩衝,就清楚該緩衝)最好也設為2分鐘或者小於2分鐘。

 

接著我們來看一下SimplePageCachingFilter 的配置,

<filter><filter-name>indexCacheFilterfilter-name><filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter<filter-class><filter><filter-mapping><filter-name>indexCacheFilterfilter-name><url-pattern>*index.actionurl-pattern><filter-mapping>

將上述代碼加入到web.xml,那麼當開啟首頁時,你會發現2分鐘才會有一堆sql語句出現在控制台,也可以調整為5分鐘,總之一切盡在掌控之中。   

 

 

當然,如果你像緩衝首頁的部分內容時,你需要使用SimplePageFragmentCachingFilter這個filter,我看一下:

<filter><filter-name>indexCacheFilterfilter-name><filter-class>net.sf.ehcache.constructs.web.filter.SimplePageFragmentCachingFilter<filter-class>filter><filter-mapping><filter-name>indexCacheFilterfilter-name><url-pattern>*/index_right.jsp<url-pattern><filter-mapping>

如此我們將jsp頁面通過jsp:include到其他頁面,這樣就做到了頁面局部緩衝的效果,這一點貌似沒有oscache的tag好用。   

 

 

此外cachefilter中還有一個特性,就是gzip,也就是緩衝中的元素是被壓縮過的,如果用戶端瀏覽器支援壓縮的話,filter會直接返回壓縮過的流,這樣節省了頻寬,把解壓的工作交給了用戶端瀏覽即可,當然如果用戶端不支援gzip,那麼filter會把緩衝的元素拿出來解壓後在返回給用戶端瀏覽器(大多數爬蟲是不支援gzip的,所以filter也會解壓後在返迴流)。

總之,Ehcache是一個非常輕量級的緩衝實現,而且從1.2之後支援了叢集,而且是hibernate預設的緩衝provider,本文主要介紹Ehcahe對頁面緩衝的支援,但是它的功能遠不止如此,要用好緩衝,對J2ee中緩衝的原理、適用範圍、適用情境等等都需要比較深刻的理解,這樣才能用好用對緩衝。

 

為了大家通過實際例子加深瞭解與情境運用,在奉獻一個執行個體:

*在Spring中運用EhCache

    適用任意一個現有開源Cache Framework,要求可以Cache系統中service或者DAO層的get/find等方法返回結果,如果資料更新(適用了Create/update/delete),則重新整理cache中相應的內容。

    根據需求,計劃適用Spring AOP+enCache來實現這個功能,採用ehCache原因之一就是Spring提供了enCache的支援,至於為何僅僅支援ehcache而不支援oscache和jbosscache就無從得知了。

    AOP少不了攔截器,先建立一個實現了MethodInterceptor介面的攔截器,用來攔截Service/DAO的方法調用,攔截到方法後,搜尋該方法的結果在cache中是否存在,如果存在,返回cache中結果,如果不存在返回資料庫查詢結果,並將結果返回到緩衝。

public class MethodCacheInterceptor implements MethodInterceptor, InitializingBean{private static final Log logger = LogFactory.getLog(MethodCacheInterceptor.class);private Cache cache;public void setCache(Cache cache) {this.cache = cache;}public MethodCacheInterceptor() {super();}/*** 攔截Service/DAO 的方法,並尋找該結果是否存在,如果存在就返回cache 中的值,* 否則,返回資料庫查詢結果,並將查詢結果放入cache*/public Object invoke(MethodInvocation invocation) throws Throwable {String targetName = invocation.getThis().getClass().getName();String methodName = invocation.getMethod().getName();Object[] arguments = invocation.getArguments();Object result;logger.debug("Find object from cache is " + cache.getName());String cacheKey = getCacheKey(targetName, methodName, arguments);Element element = cache.get(cacheKey);Page 13 of 26if (element == null) {logger.debug("Hold up method , Get method result and create cache........!");result = invocation.proceed();element = new Element(cacheKey, (Serializable) result);cache.put(element);}return element.getValue();}/*** 獲得cache key 的方法,cache key 是Cache 中一個Element 的唯一標識* cache key 包括包名+類名+方法名,如com.co.cache.service.UserServiceImpl.getAllUser*/private String getCacheKey(String targetName, String methodName, Object[] arguments) {StringBuffer sb = new StringBuffer();sb.append(targetName).append(".").append(methodName);if ((arguments != null) && (arguments.length != 0)) {for (int i = 0; i < arguments.length; i++) {sb.append(".").append(arguments[i]);}}return sb.toString();}/*** implement InitializingBean,檢查cache 是否為空白*/public void afterPropertiesSet() throws Exception {Assert.notNull(cache, "Need a cache. Please use setCache(Cache) create it.");}}

 

 

上面的代碼可以看到,在方法invoke中,完成了搜尋cache/建立cache的功能

隨後,再建立一個攔截器MethodCacheAfterAdvice,作用是在使用者進行create/update/delete操作時來重新整理、remove相關cache內容,這個攔截器需要實現AfterRetruningAdvice介面,將會在所攔截的方法執行後執行在afterReturning(object arg0,Method arg1,Object[] arg2,object arg3)方法中所預定的操作

public class MethodCacheAfterAdvice implements AfterReturningAdvice, InitializingBean{private static final Log logger = LogFactory.getLog(MethodCacheAfterAdvice.class);private Cache cache;Page 15 of 26public void setCache(Cache cache) {this.cache = cache;}public MethodCacheAfterAdvice() {super();}public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throwsThrowable {String className = arg3.getClass().getName();List list = cache.getKeys();for(int i = 0;i<list.size();i++){String cacheKey = String.valueOf(list.get(i));if(cacheKey.startsWith(className)){cache.remove(cacheKey);logger.debug("remove cache " + cacheKey);}}}public void afterPropertiesSet() throws Exception {Assert.notNull(cache, "Need a cache. Please use setCache(Cache) create it.");}}

該方法擷取目標class的全名,如:com.co.cache.test.TestServiceImpl,然後迴圈cache的key list,重新整理/remove cache中所有和該class相關的element。   

 

 

接著就是配置encache的屬性,如最大緩衝數量、cache重新整理的時間等等。

<ehcache><diskStore path="c:\\myapp\\cache"/><defaultCachemaxElementsInMemory="1000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="true"/><cache name="DEFAULT_CACHE"maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="300000"timeToLiveSeconds="600000"overflowToDisk="true"/></ehcache>

這裡需要注意的是defaultCache定義了一個預設的cache,這個Cache不能刪除,否則會拋出No default cache is configured異常。另外由於使用攔截器來重新整理Cache內容,因此在定義cache生命週期時可以定義較大的數值,timeToIdleSeconds="30000000",timeToLiveSeconds="6000000",好像還不夠大?   

 

 

然後再將Cache和兩個攔截器配置到Spring的設定檔cache.xml中即可,需要建立兩個“切入點”,分別用於攔截不同方法名的方法。在配置application.xml並且匯入cache.xml。這樣一個簡單的Spring+Encache架構就搭建完成。

 

由於時間關係就介紹到這裡,以後有機會還會介紹Ehcache在分布式叢集系統中的使用,謝謝大家。
轉自:http://blog.csdn.net/yangchao228/article/details/7027485

Java緩衝組件 EhCache 入門教程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.