分享

EHCache技术文档

 老鼠爱上美猫 2012-07-27

0. 文档介绍... 2

0.1 文档目的... 2

0.2 文档范围... 2

0.3 读者对象... 2

0.4 参考文献... 2

0.5 术语与缩写解释... 2

1.    概述... 3

1.1背景... 3

1.2 主要特征.................................................................................................................... 3

1.3环境... 5

1.4下载资源... 5

2. EHCache页面缓存的配置... 5

2.1 EHCache的类层次模型... 5

2.2环境搭建... 6

2.3 ehcache配置文件中元素说明... 8

2.4 在工程中单独使用... 10

3. Spring中运用EHCache. 17

4. 分布式缓存集群环境配置............................................................................................... 19

4.1  集群配置方式.......................................................................................................... 19

5. 测试用例...................................................................................................................... 28

0.  文档介绍

0.1 文档目的

记录使用EHCache实现页面级的缓存以及完成集群设计的过程。

0.2 文档范围

记录使用EHCache实现页面级的缓存以及完成集群设计的过程。

0.3 读者对象

    任何有兴趣的家伙。

0.4 参考文献

提示:列出本文档的所有参考文献(可以是非正式出版物),格式如下:

[标识符] 作者,文献名称,出版单位(或归属单位),日期

 

大部分都是网络上查询的资料,很多,不列举了。

EHCache简介:

http://apps.hi.baidu.com/share/detail/7491847

http:///data/read/9082403332378.html

http://blog.csdn.net/mgoann/archive/2009/04/16/4083179.aspx

http://yuanyong./blog/691499

 

Spring整合EHCache

http:///data/read/909291257438.html

http://www./ehcache-getting-started-series-5-a-distributed-cache-cluster-environment-configuration

http://zhyt710./blog/333213

http://tech./2010-04/1270187299149502.html

http://blog.csdn.net/goodboylllll/archive/2010/04/01/5442329.aspx

 

 

 

0.5 术语与缩写解释

缩写、术语

EHCache

EHCache是一个快速的、轻量级的、易于使用的、进程内的缓存。它支持read-onlyread/write缓存,内存和磁盘缓存。是一个非常轻量级的缓存实现,而且从1.2 之后就支持了集群,目前的最新版本是2.1

 

 

 

 

 

 

 

 

 

1.      概述

1.1背景

系统缓存是位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域,目的是为了减少应用程序对物理数据源访问的次数,从而提高应用程序的运行性能. 缓存设想内存是有限的,缓存的时效性也是有限的,所以可以设定内存数量的大小,可以执行失效算法 ,可以在内存满了的时候,按照最少访问等算法将缓存直接移除或切换到硬盘上。

Ehcache Hibernate发展而来,逐渐涵盖了Cahce界的全部功能,是目前发展势头最好的一个项目。具有快速,简单,低消耗,依赖性小,扩展性强,支持对象或序列化缓存,支持缓存或元素的失效,提供LRULFUFIFO缓存策略,支持内存缓存和磁盘缓存,分布式缓存机制等等特点。

Cache 存储方式 :内存或磁盘。

官方网站http://ehcache./

 

 

1.2   主要特性

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

1.3 环境

       Windows XPJDK1.6.03Tomcat5.5EHcache2.1

注意配置好环境变量。

1.4下载资源

ehcache-2.1.0-distribution.tar.gz以及 ehcache-web-2.0.2-distribution.tar.gz

http:///projects/ehcache/

注意:同时要下载源代码,部分功能需要修改源代码,重新做包。

2. EHCache页面缓存的配置

2.1 EHCache的类层次模型

主要为三层,最上层的是CacheManager,他是操作Ehcache的入口。我们可以通过CacheManager.getInstance()获得一个单子的CacheManger,或者通过CacheManger的构造函数创建  一个新的CacheManger。每个CacheManager都管理着多个Cache。而每个Cache都以一种类Hash的方式,关联着多个 ElementElement则是我们用于存放要缓存内容的地方。

2.2 环境搭建

ehcache-2.1.0-distribution.tar.gz:以及 ehcache-web-2.0.2-distribution.tar.gz解压得到 需要将它们放置到WEB-INF/lib下。

有一个重要的配置文件ehcache.xml,可以从ehcache组件包中拷贝一个,也可以自己建立一个。需要放到classpath下 。常放的路径为/WEB-INF/classes/ehcache.xml

2.3 ehcache配置文件中元素说明

ehcach.xml配置文件主要参数的解释,其实文件里有详细的英文注释//DiskStore 配置,cache文件的存放目录 ,主要的值有
   * user.home -
用户主目录
   * user.dir -
用户当前的工作目录
   * java.io.tmpdir - Default temp file path
默认的temp文件目录
范例


1
、首先设置EhCache,建立配置文件ehcache.XML,默认的位置在class- path,可以放到你的src目录下:

?xml version="1.0" encoding="UTF-8"?
ehcache
diskStore path="Java.io.tmpdir"/
defaultCache
maxElementsInMemory="10000"
!- 缓存最大数目 -
eternal="false"
!- 缓存是否持久 -
overflowToDisk="true"
!- 是否保存到磁盘,当系统当机时-
timeToIdleSeconds="300"
!- 当缓存闲置n秒后销毁 -
timeToLiveSeconds="180"
!- 当缓存存活n秒后销毁-
diskPersistent="false"
diskExpiryThreadIntervalSeconds= "120"/

/ehcache


了解ehcache 的几个概念,

1 timeToIdleSeconds
,多长时间不访问该缓存,那么ehcache 就会清除该缓存。

2 timeToLiveSeconds
,缓存的存活时间,从开始创建的时间算起。


Ehcache
的三种清空策略                                                    
1 FIFO
first in first out,这个是大家最熟的,先进先出。
2 LFU
Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
3 LRU
Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。


首页的页面缓存

     
一个网站的首页估计是被访问的次数最多的,我们可以考虑给首页做一个页面缓存
  
缓存策略:我认为应该是某个固定时间之内不变的,比如说2分钟更新一次,以应用结构page-filter-action-service-dao-db 为例。
       
位置:页面缓存做到尽量靠近客户的地方,就是在pagefilter之间 ,这样的优点就是第一个用户请求之后,页面被缓存,第二个用户再来请求的时候,走到filter这个请求就结束了,无需再走后面的action- service-dao-db。带来的好处是服务器压力的减低和客户段页面响应速度的加快。


首页的页面缓存的存活时间,我们定的是2 分钟,那么也就是说我们的timeToLiveSeconds 应该设置为120 ,同时我们的timeToIdleSeconds 最好也设置为2 分钟,或者小于2 分钟。我们来看一下下面这个配置,这个配置片段应该放到ehcache.xml中:


SimplePageCachingFilter
是缓存的名字,maxElementsInMemory 表示内存中SimplePageCachingFilter 缓存中元素的最大数量为10maxElementsOnDisk 是指持久化该缓存的元素到硬盘上的最大数量也为10 (),eternal=false 意味着该缓存会死亡。overflowToDisk=true 意思是表示当缓存中元素的数量超过限制时,就把这些元素持久化到硬盘,如果overflowToDisk false ,那么maxElementsOnDisk 的设置就没有什么意义了。memoryStoreEvictionPolicy=LFU 是指按照缓存的hit 值来清除,也就是说缓存满了之后,新的对象需要缓存时,将会将缓存中hit 值最小的对象清除出缓存,给新的对象腾出地方来了。

接着我们来看一下SimplePageCachingFilter的配置,

XML/HTML代码

<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.action</url-pattern>  

<filter-mapping>  

 

就只需要这么多步骤,我们就可以给某个页面做一个缓存的,把上面这段配置放到你的web.xml中,那么当你打开首页的时候,你会发现,2分钟才会有一堆sql语句出现在控制台上。当然你也可以调成5分钟,总之一切都在控制中。

 

好了,缓存整个页面看上去是非常的简单,甚至都不需要写一行代码,只需要几行配置就行了,够简单吧,虽然看上去简单,但是事实上内部实现却不简单哦,有兴趣的话,大家可以看看SimplePageCachingFilter继承体系的源代码。

 

上面的配置针对的情况是缓存首页的全部,如果你只想缓存首页的部分内容时,你需要使用SimplePageFragmentCachingFilter这个filter。我们看一下如下片断:

 

XML/HTML代码

<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到其他页面,这样就做到的局部页面的缓存。这一点貌似没有oscachetag好用。

 

事实上在cachefilter中还有一个特性,就是gzip,也就是说缓存中的元素是被压缩过的,如果客户浏览器支持压缩的话,filter会直接返回压缩过的流,这样节省了带宽,把解压的工作交给了客户浏览器,如果客户的浏览器不支持gzip,那么filter会把缓存的元素拿出来解压后再返回给客户浏览器(大多数爬虫是不支持gzip的,所以filter也会解压后再返回流),这样做的优点是节省带宽,缺点就是增加了客户浏览器的负担(但是我觉得对当代的计算机而言,这个负担微乎其微)。

 

好了,如果你的页面正好也需要用到页面缓存,不防可以考虑一下ehcache,因为它实在是非常简单,而且易用。

 

总结:ehcache是一个非常轻量级的缓存实现,而且从1.2之后就支持了集群,目前的最新版本是1.3,而且是hibernate默认的缓存provider。虽然本文是介绍的是ehcache对页面缓存的支持,但是ehcache的功能远不止如此,当然要使用好缓存,对JEE中缓存的原理,使用范围,适用场景等等都需要有比较深刻的理解,这样才能用好缓存,用对缓存。

 

最后复习一下ehcache中缓存的3种清空策略:

1 FIFOfirst in first out,这个是大家最熟的,先进先出,不多讲了

2 LFU Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。

2 LRULeast Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

2.4 在工程中单独使用

1.创建CacheManager net.sf.ehcache.CacheManager

1)使用默认配置文件创建

CacheManager manager = CacheManager.create();

2)使用指定配置文件创建

CacheManager manager = CacheManager.create("src/config/ehcache.xml");

3)从classpath找寻配置文件并创建

URL url = getClass().getResource("/anothername.xml");

CacheManager manager = CacheManager.create(url);

4)通过输入流创建

InputStream fis = new FileInputStream(new File("src/config/ehcache.xml").getAbsolutePath());

try { manager = CacheManager.create(fis); } finally { fis.close(); }

2.创建Caches net.sf.ehcache.Cache

1)取得配置文件中预先 定义的sampleCache1设置,生成一个Cache

Cache cache = manager.getCache("sampleCache1");

2)设置一个名为test 的新cache,test属性为默认

CacheManager manager = CacheManager.create();

manager.addCache("test");

3)设置一个名为test 的新cache,并定义其属性

CacheManager manager = CacheManager.create();

Cache cache = new Cache("test", 1, true, false, 5, 2);

manager.addCache(cache);

4)删除cache

CacheManager singletonManager = CacheManager.create();

singletonManager.removeCache("sampleCache1"); 

3.使用Caches

1)往cache中加入元素

Element element = new Element("key1", "value1");

cache.put(new Element(element);

2)从cache中取得元素

Element element = cache.get("key1");

3)从cache中删除元素

Cache cache = manager.getCache("sampleCache1");

Element element = new Element("key1", "value1");

cache.remove("key1"); 

3.卸载CacheManager ,关闭Cache

manager.shutdown();

 

3. Spring中运用EHCache

需要使用Spring来实现一个Cache简单的解决方案,具体需求如下:使用任意一个现有开源Cache Framework,要求可以Cache系统中Service或则DAO层的get/find等方法返回结果,如果数据更新(使用Create/update/delete方法),则刷新cache中相应的内容。

根据需求,计划使用Spring AOP + ehCache来实现这个功能,采用ehCache原因之一是Spring提供了ehCache的支持,至于为何仅仅支持ehCache而不支持osCacheJBossCache无从得知(Hibernate???),但毕竟Spring提供了支持,可以减少一部分工作量:)。二是后来实现了OSCacheJBoss Cache的方式后,经过简单测试发现几个Cache在效率上没有太大的区别(不考虑集群),决定采用ehCahce

AOP
嘛,少不了拦截器,先创建一个实现了MethodInterceptor接口的拦截器,用来拦截Service/DAO的方法调用,拦截到方法后,搜索该方法的结果在cache中是否存在,如果存在,返回cache中的缓存结果,如果不存在,返回查询数据库的结果,并将结果缓存到cache中。

MethodCacheInterceptor.java

 

Java代码

package com.co.cache.ehcache;    

import java.io.Serializable;    

import net.sf.ehcache.Cache;    

import net.sf.ehcache.Element;    

import org.aopalliance.intercept.MethodInterceptor;    

import org.aopalliance.intercept.MethodInvocation;    

import org.apache.commons.logging.Log;    

import org.apache.commons.logging.LogFactory;    

import org.springframework.beans.factory.InitializingBean;    

import org.springframework.util.Assert;    

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);    

  

   if (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 keyCache中一个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.");    

}    

  

}  

 

 

 

上面的代码中可以看到,在方法public Object invoke(MethodInvocation invocation) 中,完成了搜索Cache/新建cache的功能。

 

 

Java代码

Element element = cache.get(cacheKey);  

 

 

这句代码的作用是获取cache中的element,如果cacheKey所对应的element不存在,将会返回一个null

 

 

 

Java代码

result = invocation.proceed();  

 

 

这句代码的作用是获取所拦截方法的返回值,详细请查阅AOP相关文档。

 

随后,再建立一个拦截器MethodCacheAfterAdvice,作用是在用户进行create/update/delete操作时来刷新/remove相关cache内容,这个拦截器实现了AfterReturningAdvice接口,将会在所拦截的方法执行后执行在public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3)方法中所预定的操作

 

 

Java代码

package com.co.cache.ehcache;    

  

import java.lang.reflect.Method;    

import java.util.List;    

  

import net.sf.ehcache.Cache;    

  

import org.apache.commons.logging.Log;    

import org.apache.commons.logging.LogFactory;    

import org.springframework.aop.AfterReturningAdvice;    

import org.springframework.beans.factory.InitializingBean;    

import org.springframework.util.Assert;    

  

public class MethodCacheAfterAdvice implements AfterReturningAdvice, InitializingBean    

{    

private static final Log logger = LogFactory.getLog(MethodCacheAfterAdvice.class);    

  

private Cache cache;    

  

public void setCache(Cache cache) {    

   this.cache = cache;    

}    

  

public MethodCacheAfterAdvice() {    

   super();    

}    

  

public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {    

   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.");    

}    

  

}  

 

 

上面的代码很简单,实现了afterReturning方法实现自AfterReturningAdvice接口,方法中所定义的内容将会在目标方法执行后执行,在该方法中 的作用是获取目标class的全名,如:com.co.cache.test.TestServiceImpl,然后循环cachekey listremove cache中所有和该class相关的element

 

 

Java代码

String className = arg3.getClass().getName();  

 

 

随后,开始配置ehCache的属性,ehCache需要一个xml文件来设置ehCache相关的一些属性,如最大缓存数量、cache刷新的时间等等.

ehcache.xml

 

 

Java代码

<ehcache>    

<diskStore path="c:\\myapp\\cache"/>    

<defaultCache    

maxElementsInMemory="1000"    

eternal="false"    

timeToIdleSeconds="120"    

timeToLiveSeconds="120"    

overflowToDisk="true"    

/>    

<cache name="DEFAULT_CACHE"    

maxElementsInMemory="10000"    

eternal="false"    

timeToIdleSeconds="300000"    

timeToLiveSeconds="600000"    

overflowToDisk="true"    

/>    

</ehcache>  

 

 

配置每一项的详细作用不再详细解释,有兴趣的请google  ,这里需要注意一点defaultCache标签定义了一个默认的Cache,这个Cache是不能删除的,否则会抛出No default cache is configured异常。另外,由于使用拦截器来刷新Cache内容,因此在定义cache生命周期时可以定义较大的数值,timeToIdleSeconds="300000" timeToLiveSeconds="600000",好像还不够大? 

 

然后,在将Cache和两个拦截器配置到Spring,这里没有使用2.0里面AOP的标签。

cacheContext.xml

 

 

Java代码

<?xml version="1.0" encoding="UTF-8"?>    

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd">    

<beans>    

<!-- 引用ehCache的配置 -->    

<bean id="defaultCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">    

   <property name="configLocation">    

   <value>ehcache.xml</value>    

   </property>    

</bean>    

  

<!-- 定义ehCache的工厂,并设置所使用的Cache name -->    

<bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">    

   <property name="cacheManager">    

   <ref local="defaultCacheManager"/>    

   </property>    

   <property name="cacheName">    

      <value>DEFAULT_CACHE</value>    

   </property>    

</bean>    

  

<!-- find/create cache拦截器 -->    

<bean id="methodCacheInterceptor" class="com.co.cache.ehcache.MethodCacheInterceptor">    

   <property name="cache">    

   <ref local="ehCache" />    

   </property>    

</bean>    

<!-- flush cache拦截器 -->    

<bean id="methodCacheAfterAdvice" class="com.co.cache.ehcache.MethodCacheAfterAdvice">    

   <property name="cache">    

   <ref local="ehCache" />    

   </property>    

</bean>    

  

<bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">    

   <property name="advice">    

   <ref local="methodCacheInterceptor"/>    

   </property>    

   <property name="patterns">    

   <list>    

      <value>.*find.*</value>    

      <value>.*get.*</value>    

   </list>    

   </property>    

</bean>    

<bean id="methodCachePointCutAdvice" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">    

   <property name="advice">    

   <ref local="methodCacheAfterAdvice"/>    

   </property>     

   <property name="patterns">    

   <list>    

      <value>.*create.*</value>    

      <value>.*update.*</value>    

      <value>.*delete.*</value>    

   </list>    

   </property>    

</bean>    

</beans>  

 

 

上面的代码最终创建了两个"切入点"methodCachePointCutmethodCachePointCutAdvice,分别用于拦截不同方法名的方法,可以根据需要任意增加所需要拦截方法的名称。

需要注意的是

 

 

Java代码

<bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">    

   <property name="cacheManager">    

   <ref local="defaultCacheManager"/>    

   </property>    

   <property name="cacheName">    

      <value>DEFAULT_CACHE</value>    

   </property>    

</bean>  

 

 

如果cacheName属性内设置的nameehCache.xml中无法找到,那么将使用默认的cache(defaultCache标签定义).

 

事实上到了这里,一个简单的Spring + ehCache Framework基本完成了,为了测试效果,举一个实际应用的例子,定义一个TestService和它的实现类TestServiceImpl,里面包含

 

两个方法getAllObject()updateObject(Object Object),具体代码如下

TestService.java

 

 

Java代码

package com.co.cache.test;    

  

import java.util.List;    

  

public interface TestService {    

public List getAllObject();    

  

public void updateObject(Object Object);    

}  

 

 

 

TestServiceImpl.java

 

 

Java代码

package com.co.cache.test;    

  

import java.util.List;    

  

public class TestServiceImpl implements TestService    

{    

public List getAllObject() {    

   System.out.println("---TestServiceCache内不存在该element,查找并放入Cache");    

   return null;    

}    

  

public void updateObject(Object Object) {    

   System.out.println("---TestService:更新了对象,这个Class产生的cache都将被remove");    

}    

}  

 

 

使用Spring提供的AOP进行配置

applicationContext.xml

 

 

XML/HTML代码

<?xml version="1.0" encoding="UTF-8"?>    

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd">    

  

<beans>    

<import resource="cacheContext.xml"/>    

  

<bean id="testServiceTarget" class="com.co.cache.test.TestServiceImpl"/>    

  

<bean id="testService" class="org.springframework.aop.framework.ProxyFactoryBean">    

   <property name="target">     

      <ref local="testServiceTarget"/>    

   </property>    

   <property name="interceptorNames">    

   <list>    

      <value>methodCachePointCut</value>    

      <value>methodCachePointCutAdvice</value>    

   </list>    

   </property>     

</bean>    

</beans>  

 

 

这里一定不能忘记import cacheContext.xml文件,不然定义的两个拦截器就没办法使用了。

 

最后,写一个测试的代码

MainTest.java

 

 

Java代码

(DEFAULT_CONTEXT_FILE);    

   TestService testService = (TestService)context.getBean("testService");    

  

   System.out.println("1--第一次查找并创建cache");    

   testService.getAllObject();    

      

   System.out.println("2--cache中查找");    

   testService.getAllObject();    

      

   System.out.println("3--remove cache");    

   testService.updateObject(null);    

      

   System.out.println("4--需要重新查找并创建cache");    

   testService.getAllObject();    

}    

}   

 

 

运行,结果如下

 

 

Java代码

1--第一次查找并创建cache    

---TestServiceCache内不存在该element,查找并放入Cache    

2--cache中查找    

3--remove cache    

---TestService:更新了对象,这个Class产生的cache都将被remove    

4--需要重新查找并创建cache    

---TestServiceCache内不存在该element,查找并放入Cache  

 

 

 

大功告成  .可以看到,第一步执行getAllObject(),执行TestServiceImpl内的方法,并创建了cache,在第二次执行getAllObject()方法时,由于cache有该方法的缓存,直接从cacheget出方法的结果,所以没有打印出TestServiceImpl中的内容,而第三步,调用了updateObject方法,和TestServiceImpl相关的cacheremove,所以在第四步执行时,又执行TestServiceImpl中的方法,创建Cache

 

网上也有不少类似的例子,但是很多都不是很完备,自己参考了一些例子的代码,其实在spring-modules中也提供了对几种cache的支持,ehCacheOSCacheJBossCache这些,看了一下,基本上都是采用类似的方式,只不过封装的更完善一些,主要思路也还是SpringAOP,有兴趣的可以研究一下。

4. 分布式缓存集群环境配置

4.1集群配置方式

ehcache提供三种网络连接策略来实现集群,rmi,jgroup还有jms这里只说rmi方式。同时ehcache可以可以实现多播的方式实现集群。也可以手动指定集群主机序列实现集群,本例应用手动指定。

这里说点题外话,本来看着分发包中的原来的例子配置是一件不怎么难的事情,应该很容易就能实现。但是一开始,我是在我的linux主机上和我的主操作系统windows上实现集群配置。结果反过来弄过去,都没有成功。然后在网上找一些别人的配置经验,竟然都是配置片段,没有完整的实例文件。结果配置半天没成功。但我怀疑是我的linux系统有些地方可能没有配置好,于是先不管他。有开启了我的另一个windows主机。然后把程序部署上去,竟然一次试验成功。高兴的同时,我得发句话不要把代码片段称作实例,这很不负责任。同时还存在一个问题,linux下没有部署成功的原因有待查明

具体说明:配置cacheManagerPeerListenerFactory是配宿主主机配置监听程序,来发现其他主机发来的同步请求配置cacheManagerPeerProviderFactory是指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机。

下面的例子的测试过程是:主机B缓存开启,并从名为UserCache的缓存中循环抓取键值为“key1”的元素,直到取到,才退出循环。主机A缓存启动,并在名为UserCache的缓存中放入键值为“key1”的元素。显然,如果主机B取到的元素,那么就证明同步成功,也就是集群成功。所以在测试过程中先启动主机B的测试程序,在启动主机A的测试程序。

下面具体说配置文件以及测试程序:

1. 主机A的配置文件以及测试源代码

config/ehcache_cluster.xml

Xml代码

  1. <ehcache xmlns:xsi="http://www./2001/XMLSchema-instance"  
  2.     xsi:noNamespaceSchemaLocation="ehcache.xsd">  
  3.     <cacheManagerPeerProviderFactory  
  4.         class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"  
  5.         properties="peerDiscovery=manual,    
  6.         rmiUrls=//192.168.1.254:40000/UserCache" />  
  7.   
  8.     <cacheManagerPeerListenerFactory  
  9.         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"  
  10.         properties="hostName=192.168.1.126,port=40000,socketTimeoutMillis=120000" />  
  11.   
  12.     <defaultCache maxElementsInMemory="10000" eternal="false"  
  13.         timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"  
  14.         diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"  
  15.         diskPersistent="false" diskExpiryThreadIntervalSeconds="120"  
  16.         memoryStoreEvictionPolicy="LRU">  
  17.         <cacheEventListenerFactory  
  18.             class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />  
  19.     </defaultCache>  
  20.   
  21.     <cache name="UserCache" maxElementsInMemory="1000" eternal="false"  
  22.         timeToIdleSeconds="100000" timeToLiveSeconds="100000"  
  23.         overflowToDisk="false">  
  24.         <cacheEventListenerFactory  
  25.             class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />  
  26.     </cache>  
  27. </ehcache>  

<ehcache xmlns:xsi="http://www./2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="ehcache.xsd">

<cacheManagerPeerProviderFactory

  class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"

  properties="peerDiscovery=manual,

        rmiUrls=//192.168.1.254:40000/UserCache" />

 

<cacheManagerPeerListenerFactory

  class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"

  properties="hostName=192.168.1.126,port=40000,socketTimeoutMillis=120000" />

 

<defaultCache maxElementsInMemory="10000" eternal="false"

  timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"

  diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"

  diskPersistent="false" diskExpiryThreadIntervalSeconds="120"

  memoryStoreEvictionPolicy="LRU">

  <cacheEventListenerFactory

   class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />

</defaultCache>

 

<cache name="UserCache" maxElementsInMemory="1000" eternal="false"

  timeToIdleSeconds="100000" timeToLiveSeconds="100000"

  overflowToDisk="false">

  <cacheEventListenerFactory

   class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />

</cache>

</ehcache>

 tutorial/UsingCacheCluster

Java代码

  1. package tutorial;   
  2.   
  3. import java.net.URL;   
  4.   
  5. import net.sf.ehcache.Cache;   
  6. import net.sf.ehcache.CacheManager;   
  7. import net.sf.ehcache.Element;   
  8.   
  9. public class UsingCacheCluster {   
  10.   
  11.     public static void main(String[] args) throws Exception {   
  12.         URL url = UsingCacheCluster.class.getClassLoader().getResource(   
  13.                 "config/ehcache_cluster.xml");   
  14.         CacheManager manager = new CacheManager(url);   
  15.         //取得Cache   
  16.         Cache cache = manager.getCache("UserCache");   
  17.         Element element = new Element("key1", "value1");   
  18.         cache.put(element);   
  19.   
  20.         Element element1 = cache.get("key1");   
  21.         System.out.println(element1.getValue());   
  22.     }   
  23.   
  24. }  

2.  主机B上的配置文件以及测试代码

config/ehcache_cluster.xml

Xml代码

  1. <ehcache xmlns:xsi="http://www./2001/XMLSchema-instance"  
  2.     xsi:noNamespaceSchemaLocation="ehcache.xsd">  
  3.     <cacheManagerPeerProviderFactory  
  4.         class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"  
  5.         properties="peerDiscovery=manual,    
  6.         rmiUrls=//192.168.1.126:40000/UserCache" />  
  7.   
  8.     <cacheManagerPeerListenerFactory  
  9.         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"  
  10.         properties="hostName=192.168.1.254,port=40000, socketTimeoutMillis=120000" />  
  11.   
  12.     <defaultCache maxElementsInMemory="10000" eternal="false"  
  13.         timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"  
  14.         diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"  
  15.         diskPersistent="false" diskExpiryThreadIntervalSeconds="120"  
  16.         memoryStoreEvictionPolicy="LRU">  
  17.         <cacheEventListenerFactory  
  18.             class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />  
  19.     </defaultCache>  
  20.   
  21.     <cache name="UserCache" maxElementsInMemory="1000" eternal="false"  
  22.         timeToIdleSeconds="100000" timeToLiveSeconds="100000"  
  23.         overflowToDisk="false">  
  24.         <cacheEventListenerFactory  
  25.             class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />  
  26.     </cache>  
  27. </ehcache>  

<ehcache xmlns:xsi="http://www./2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="ehcache.xsd">

<cacheManagerPeerProviderFactory

  class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"

  properties="peerDiscovery=manual,

        rmiUrls=//192.168.1.126:40000/UserCache" />

 

<cacheManagerPeerListenerFactory

  class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"

  properties="hostName=192.168.1.254,port=40000, socketTimeoutMillis=120000" />

 

<defaultCache maxElementsInMemory="10000" eternal="false"

  timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"

  diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"

  diskPersistent="false" diskExpiryThreadIntervalSeconds="120"

  memoryStoreEvictionPolicy="LRU">

  <cacheEventListenerFactory

   class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />

</defaultCache>

 

<cache name="UserCache" maxElementsInMemory="1000" eternal="false"

  timeToIdleSeconds="100000" timeToLiveSeconds="100000"

  overflowToDisk="false">

  <cacheEventListenerFactory

   class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />

</cache>

</ehcache>

 

 

tutorial/UsingCacheCluster

Java代码

  1. package tutorial;   
  2.   
  3. import java.net.URL;   
  4.   
  5. import net.sf.ehcache.Cache;   
  6. import net.sf.ehcache.CacheManager;   
  7. import net.sf.ehcache.Element;   
  8.   
  9. public class UsingCacheCluster {   
  10.   
  11.     public static void main(String[] args) throws Exception {   
  12.         URL url = UsingCacheCluster.class.getClassLoader().getResource(   
  13.                 "config/ehcache_cluster.xml");   
  14.         CacheManager manager = new CacheManager(url);   
  15.         //取得Cache   
  16.         Cache cache = manager.getCache("UserCache");   
  17.   
  18.         while(true) {   
  19.             Element e = cache.get("key1");   
  20.             if(e != null) {   
  21.                 System.out.println(e.getValue());   
  22.                 break;   
  23.             }   
  24.             Thread.sleep(1000);   
  25.         }   
  26.     }   
  27.   
  28. }  

 

5. 测试用例

直接进入测试文档EHCache测试文档.docx

 

 

 

 

 

 


分布式同步缓存要让这边的cache知道对方的cache,叫做Peer Discovery(成员发现)
EHCache
实现成员发现的方式有两种:
第一,自动查找
自动的发现方式用 TCP 广播机制来确定和维持一个广播组。它只需要一个简单的配置可以自动的在组中添加和移除成员。在集群中也不需要什么优化服务器的知识,这是默认推荐的。
成员每秒向群组发送一个心跳。如果一个成员 5 秒种都没有发出信号它将被群组移除。如果一个新的成员发送了一个心跳它将被添加进群组。
任何一个用这个配置安装了复制功能的 cache 都将被其他的成员发现并标识为可用状态。
要设置自动的成员发现,需要指定ehcache配置文件中cacheManagerPeerProviderFactory元素的 properties属性,就像下面这样: 
peerDiscovery=automatic multicastGroupAddress=multicast address | multicast host name
multicastGroupPort=port timeToLive=0-255 (timeToLive
属性详见常见问题部分的描述)
示例
假设你在集群中有两台服务器。你希望同步 sampleCache1 sampleCache2。每台独立的服务器都要有这样的配置:
配置 server1 server2

Xml代码  

  1. <cacheManagerPeerProviderFactory   
  2.  class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"   
  3.  properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,   
  4.  multicastGroupPort=4446, timeToLive=32"/>   

<cacheManagerPeerProviderFactory

 class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"

 properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,

 multicastGroupPort=4446, timeToLive=32"/>



第二,手动查找
进行手动成员配置要知道每个监听器的 IP 地址和端口。成员不能在运行时动态地添加和移除。在技术上很难使用广播的情况下就可以手动成员发现,例如在集群的服务器之间有一个不能传送广播报文的路由器。你也可以用手动成员发现进行单向的数据复制,只让server2 知道 server1 server1 不知道 server2
配置手动成员发现,需要指定 ehcache 配置文件中 cacheManagerPeerProviderFactory properties属性,像下面这样:
peerDiscovery=manual rmiUrls=//server:port/cacheName, ... rmiUrls
配置的是服务器 cache peers 的列表。注意不要重复配置。
示例
假设你在集群中有两台服务器。你要同步 sampleCache1 sampleCache2。下面是每个
服务器需要的配置:
配置 server1

Xml代码  

  1. <cacheManagerPeerProviderFactory   
  2.  class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"   
  3.  properties="peerDiscovery=manual,   
  4.  rmiUrls=//server2:40001/sampleCache11|//server2:40001/sampleCache12"/>  

<cacheManagerPeerProviderFactory

 class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"

 properties="peerDiscovery=manual,

 rmiUrls=//server2:40001/sampleCache11|//server2:40001/sampleCache12"/>


配置 server2

Xml代码  

  1. <cacheManagerPeerProviderFactory   
  2.  class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"   
  3.  properties="peerDiscovery=manual,   
  4.  rmiUrls=//server1:40001/sampleCache11|//server1:40001/sampleCache12"/>  

<cacheManagerPeerProviderFactory

 class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"

 properties="peerDiscovery=manual,

 rmiUrls=//server1:40001/sampleCache11|//server1:40001/sampleCache12"/>



给个完整的配置:

Xml代码  

  1. <ehcache xmlns:xsi="http://www./2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">   
  2. <cacheManagerPeerProviderFactory class=   
  3. "net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"   
  4. properties="peerDiscovery=manual,   
  5. rmiUrls=//10.129.0.203:40000/UserCache |//10.129.0.203:40000/ReturnCache"/>   
  6.   
  7. <cacheManagerPeerListenerFactory   
  8. class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"   
  9. properties="hostName=10.129.0.202,port=40000, socketTimeoutMillis=120000"/>   
  10.   
  11. <defaultCache   
  12. maxElementsInMemory="10000"   
  13. eternal="false"   
  14. timeToIdleSeconds="120"   
  15. timeToLiveSeconds="120"   
  16. overflowToDisk="true"   
  17. diskSpoolBufferSizeMB="30"   
  18. maxElementsOnDisk="10000000"   
  19. diskPersistent="false"   
  20. diskExpiryThreadIntervalSeconds="120"   
  21. memoryStoreEvictionPolicy="LRU"   
  22. <cacheEventListenerFactory   
  23. class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>   
  24. />   
  25.   
  26. <cache name="UserCache"   
  27. maxElementsInMemory="1000"   
  28. eternal="false"   
  29. timeToIdleSeconds="100000"   
  30. timeToLiveSeconds="100000"   
  31. overflowToDisk="false">   
  32. <cacheEventListenerFactory   
  33. class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>   
  34. </cache>   

<ehcache xmlns:xsi="http://www./2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">

<cacheManagerPeerProviderFactory class=

"net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"

properties="peerDiscovery=manual,

rmiUrls=//10.129.0.203:40000/UserCache |//10.129.0.203:40000/ReturnCache"/>

 

<cacheManagerPeerListenerFactory

class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"

properties="hostName=10.129.0.202,port=40000, socketTimeoutMillis=120000"/>

 

<defaultCache

maxElementsInMemory="10000"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"

diskSpoolBufferSizeMB="30"

maxElementsOnDisk="10000000"

diskPersistent="false"

diskExpiryThreadIntervalSeconds="120"

memoryStoreEvictionPolicy="LRU"

<cacheEventListenerFactory

class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>

/>

 

<cache name="UserCache"

maxElementsInMemory="1000"

eternal="false"

timeToIdleSeconds="100000"

timeToLiveSeconds="100000"

overflowToDisk="false">

<cacheEventListenerFactory

class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>

</cache>



引用

属性解释:
必须属性:
        name:
设置缓存的名称,用于标志缓存,惟一
        maxElementsInMemory:
在内存中最大的对象数量
        maxElementsOnDisk
:在DiskStore中的最大对象数量,如为0,则没有限制
        eternal
:设置元素是否永久的,如果为永久,则timeout忽略
        overflowToDisk
:是否当memory中的数量达到限制后,保存到Disk

可选的属性:
        timeToIdleSeconds
:设置元素过期前的空闲时间
        timeToLiveSeconds
:设置元素过期前的活动时间
        diskPersistent
:是否disk store在虚拟机启动时持久化。默认为false
   diskExpiryThreadIntervalSeconds:
运行disk终结线程的时间,默认为120
        memoryStoreEvictionPolicy
:策略关于Eviction

缓存子元素:
   
    cacheEventListenerFactory
:注册相应的的缓存监听类,用于处理缓存事件,如put,remove,update,expire
    bootstrapCacheLoaderFactory:
指定相应的BootstrapCacheLoader,用于在初始化缓存,以及自动设置。



  • 集群的作用有两方面吧,第一,负载分流。第二,安全性。


   
在我看来,如果一个web应用的访问量不是很多的话,集群和非集群的效果相差不了多少,甚至有的时候集群会消耗更多的资源,导致垃圾回收频繁,内存占用率高等的现象。当然,如果访问量大,那当然是集群的效果会好很多。
        
那在访问量小的时候是不是就不用做集群呢,答案是否定的。集群的另外一个好处就是数据和状态的安全性,EHCache会自动同步集群中服务器的缓存,当一 台服务器挂掉后,另外的服务器可以马上接上来,防止用户状态数据丢失,所以,对安全性的保障是十分有效的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ehcache提供三种网络连接策略来实现集群,rmi,jgroup还有jms。同时ehcache可以可以实现多播的方式实现集群,也可以手动指定集群主机序列实现集群。

首推荐官方文档:http:///documentation/distributed_caching.html

 

下面是来自javaeye的一篇文章,略有补充,算是实践总结吧

Ehcache支持的分布式缓存支持有三种RMIJGroupsJMS,这里介绍下MRIJGrpups两种方式,Ehcache使用版本为1.5.0,关于ehcache的其他信息请参考http://ehcache./EhcacheUserGuide.html

关于jgroups的信息请参考http://www./manual/html_single/index.html

环境为两台机器 server1 ip192.168.2.154server2 ip192.168.2.23

1. RMI方式:

rmi的方式配置要点(下面均是server1上的配置,server2上的只需要把ip兑换即可)

a. 配置PeerProvider

Xml代码

<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" 
properties="peerDiscovery=manual,rmiUrls=//192.168.2.23:40001/userCache|//192.168.2.23:40001/resourceCache" />
 

配置中通过手动方式同步sever2中的userCacheresourceCache

b. 配置CacheManagerPeerListener

Xml代码

<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" 
properties="hostName=192.168.2.154, port=40001,socketTimeoutMillis=2000" />
 

配置中server1监听本机40001端口。

c. 在每一个cache中添加cacheEventListener,例子如下:

Xml代码

<cache name="userCache" maxElementsInMemory="10000" eternal="true" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="120">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"     properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy= false, replicateRemovals= true " />
</cache>

属性解释:
必须属性:
        name:
设置缓存的名称,用于标志缓存,惟一

        maxElementsInMemory:
在内存中最大的对象数量

        maxElementsOnDisk
:在DiskStore中的最大对象数量,如为0,则没有限制

        eternal
:设置元素是否永久的,如果为永久,则timeout忽略

        overflowToDisk
:是否当memory中的数量达到限制后,保存到
Disk
可选的属性:

        timeToIdleSeconds
:设置元素过期前的空闲时间

        timeToLiveSeconds
:设置元素过期前的活动时间

        diskPersistent
:是否disk store在虚拟机启动时持久化。默认为
false
   diskExpiryThreadIntervalSeconds:
运行disk终结线程的时间,默认为120

        memoryStoreEvictionPolicy
:策略关于
Eviction
缓存子元素:

    cacheEventListenerFactory
:注册相应的的缓存监听类,用于处理缓存事件,如put,remove,update,
expire
    bootstrapCacheLoaderFactory:
指定相应的BootstrapCacheLoader,用于在初始化缓存,以及自动设置。

 

 

参考另外一篇学习笔记http://wozailongyou./blog/230252,也有集群的说明

2. JGroups方式:

ehcache 1.5.0之后版本支持的一种方式,配置起来比较简单,要点:

a. 配置PeerProvider,使用tcp的方式,例子如下:

Xml代码

<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
        properties="connect=TCP(start_port=7800):
        TCPPING(initial_hosts=192.168.2.154[7800],192.168.2.23[7800];port_range=10;timeout=3000;
        num_initial_members=3;up_thread=true;down_thread=true):
        VERIFY_SUSPECT(timeout=1500;down_thread=false;up_thread=false):
        pbcast.NAKACK(down_thread=true;up_thread=true;gc_lag=100;retransmit_timeout=3000):
        pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;
        print_local_addr=false;down_thread=true;up_thread=true)" 
        propertySeparator="::" />

 

b.为每个cache添加cacheEventListener

Xml代码

<cache name="userCache" maxElementsInMemory="10000" eternal="true"
        overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0"
        diskPersistent="false" diskExpiryThreadIntervalSeconds="120">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            properties="replicateAsynchronously=true, replicatePuts=true,
                   replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/>
</cache>

JGroup方式配置的两个server上的配置文件一样,若有多个server,在initial_hosts中将server ip加上即可。

一个完整的ehcache.xml文件:

Xml代码

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www./2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache./ehcache.xsd">
    <diskStore path="java.io.tmpdir" />
 
    <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
        properties="connect=TCP(start_port=7800):
        TCPPING(initial_hosts=192.168.2.154[7800],192.168.2.23[7800];port_range=10;timeout=3000;
        num_initial_members=3;up_thread=true;down_thread=true):
        VERIFY_SUSPECT(timeout=1500;down_thread=false;up_thread=false):
        pbcast.NAKACK(down_thread=true;up_thread=true;gc_lag=100;retransmit_timeout=3000):
        pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;
        print_local_addr=false;down_thread=true;up_thread=true)" 
        propertySeparator="::" />
 
    <defaultCache maxElementsInMemory="10000" eternal="true"
        overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0"
        diskPersistent="false" diskExpiryThreadIntervalSeconds="120">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            properties="replicateAsynchronously=true, replicatePuts=true,
                   replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/>
    </defaultCache>
 
    <cache name="velcroCache" maxElementsInMemory="10000" eternal="true"
        overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0"
        diskPersistent="false" diskExpiryThreadIntervalSeconds="120">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            properties="replicateAsynchronously=true, replicatePuts=true,
                   replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/>
    </cache>
    <cache name="userCache" maxElementsInMemory="10000" eternal="true"
        overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0"
        diskPersistent="false" diskExpiryThreadIntervalSeconds="120">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            properties="replicateAsynchronously=true, replicatePuts=true,
                   replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/>
    </cache>
    <cache name="resourceCache" maxElementsInMemory="10000"
        eternal="true" overflowToDisk="true" timeToIdleSeconds="0"
        timeToLiveSeconds="0" diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            properties="replicateAsynchronously=true, replicatePuts=true,
                   replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/>
    </cache>
</ehcache>

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多