`
happyqing
  • 浏览: 3205976 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ehcache 中ehcache.xml 配置详解和示例

阅读更多

Ehcache 中ehcache.xml 配置详解和示例

 

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">   
  
    <diskStore path="java.io.tmpdir"/>   
  
    <!--   
    Mandatory Default Cache configuration. These settings will be applied to caches   
    created programmtically using CacheManager.add(String cacheName)   
    -->   
    <!--   
       name:缓存名称。   
       maxElementsInMemory:缓存最大个数。   
       eternal:对象是否永久有效,一但设置了,timeout将不起作用。   
       timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。   
       timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。   
       overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。   
       diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。   
       maxElementsOnDisk:硬盘最大缓存个数。   
       diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.   
       diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。   
       memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。   
       clearOnFlush:内存数量最大时是否清除。   
    -->   
    <defaultCache   
            maxElementsInMemory="10000"  
            eternal="false"  
            timeToIdleSeconds="120"  
            timeToLiveSeconds="120"  
            overflowToDisk="true"  
            maxElementsOnDisk="10000000"  
            diskPersistent="false"  
            diskExpiryThreadIntervalSeconds="120"  
            memoryStoreEvictionPolicy="LRU"  
            />   
</ehcache>  

 

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

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

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

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

---------------------------------------------------------------------------------------------------------------------

配置元素说明:

diskStore:配置DiskStore,当需要使用磁盘保存的时候,需要对象实现序列化接口

    属性:path 配置文件存储位置,如user.home,user.dir,java.io.tmpdir

defaultCache: 默认缓存配置

    必须属性:
        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,用于在初始化缓存,以及自动设置。

---------------------------------------------------------------------------------------------------------------------

 

在开发高并发量,高性能的网站应用系统时,缓存Cache起到了非常重要的作用。本文主要介绍EHCache的使用,以及使用EHCache的实践经验。
笔者使用过多种基于Java的开源Cache组件,其中包括OSCache、JBossCache、EHCache。OSCache功能强大,使用灵活,可用于对象缓存、Filter缓存以及在JSP中直接使用cache标签。笔者在最近的使用过程中发现,在并发量较高时,OSCache会出现线程阻塞和数据错误,通过分析源代码发现是其内部实现的缺陷。JBossCache最大的优点是支持基于对象属性的集群同步,不过JBossCache的配置使用都较复杂,在并发量较高的情况下,对象属性数据在集群中同步也会加大系统的开销。以上两种Cache本文仅作简单介绍,不做深入探讨。
EHCache是来自sourceforge(http://ehcache.sourceforge.net/)的开源项目,也是纯Java实现的简单、快速的Cache组件。EHCache支持内存和磁盘的缓存,支持LRU、LFU和FIFO多种淘汰算法,支持分布式的Cache,可以作为Hibernate的缓存插件。同时它也能提供基于Filter的Cache,该Filter可以缓存响应的内容并采用Gzip压缩提高响应速度。

EHCache API的基本用法
首先介绍CacheManager类。它主要负责读取配置文件,默认读取CLASSPATH下的ehcache.xml,根据配置文件创建并管理Cache对象。
// 使用默认配置文件创建CacheManager
CacheManager manager = CacheManager.create();
// 通过manager可以生成指定名称的Cache对象
Cache cache = cache = manager.getCache("demoCache");
// 使用manager移除指定名称的Cache对象
manager.removeCache("demoCache");
可以通过调用manager.removalAll()来移除所有的Cache。通过调用manager的shutdown()方法可以关闭CacheManager。
有了Cache对象之后就可以进行一些基本的Cache操作,例如:
//往cache中添加元素
Element element = new Element("key", "value");
cache.put(element);
//从cache中取回元素
Element element = cache.get("key");
element.getValue();
//从Cache中移除一个元素
cache.remove("key");
可以直接使用上面的API进行数据对象的缓存,这里需要注意的是对于缓存的对象都是必须可序列化的。在下面的篇幅中笔者还会介绍EHCache和Spring、Hibernate的整合使用。

配置文件
配置文件ehcache.xml中命名为demoCache的缓存配置:
<cache name="demoCache"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU" />

各配置参数的含义:
maxElementsInMemory:缓存中允许创建的最大对象数
eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
overflowToDisk:内存不足时,是否启用磁盘缓存。
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。LRU和FIFO算法这里就不做介绍。LFU算法直接淘汰使用比较少的对象,在内存保留的都是一些经常访问的对象。对于大部分网站项目,该算法比较适用。
如果应用需要配置多个不同命名并采用不同参数的Cache,可以相应修改配置文件,增加需要的Cache配置即可。

利用Spring APO整合EHCache
首先,在CLASSPATH下面放置ehcache.xml配置文件。在Spring的配置文件中先添加如下cacheManager配置:
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
</bean>
配置demoCache:
<bean id="demoCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
<property name="cacheName">
<value>demoCache</value>
</property>
</bean>
接下来,写一个实现org.aopalliance.intercept.MethodInterceptor接口的拦截器类。有了拦截器就可以有选择性的配置想要缓存的 bean 方法。如果被调用的方法配置为可缓存,拦截器将为该方法生成 cache key 并检查该方法返回的结果是否已缓存。如果已缓存,就返回缓存的结果,否则再次执行被拦截的方法,并缓存结果供下次调用。具体代码如下:
public class MethodCacheInterceptor implements MethodInterceptor,
InitializingBean {

private Cache cache;


public void setCache(Cache cache) {
this.cache = cache;
}


public void afterPropertiesSet() throws Exception {
Assert.notNull(cache,
"A cache is required. Use setCache(Cache) to provide one.");
}


public Object invoke(MethodInvocation invocation) throws Throwable {
String targetName = invocation.getThis().getClass().getName();
String methodName = invocation.getMethod().getName();
Object[] arguments = invocation.getArguments();
Object result;

String cacheKey = getCacheKey(targetName, methodName, arguments);
Element element = null;
synchronized (this){
element = cache.get(cacheKey);

if (element == null) {
//调用实际的方法
result = invocation.proceed();
element = new Element(cacheKey, (Serializable) result);
cache.put(element);
}
}
return element.getValue();
}


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();
}
}
synchronized (this)这段代码实现了同步功能。为什么一定要同步?Cache对象本身的get和put操作是同步的。如果我们缓存的数据来自数据库查询,在没有这段同步代码时,当key不存在或者key对应的对象已经过期时,在多线程并发访问的情况下,许多线程都会重新执行该方法,由于对数据库进行重新查询代价是比较昂贵的,而在瞬间大量的并发查询,会对数据库服务器造成非常大的压力。所以这里的同步代码是很重要的。

接下来,继续完成拦截器和Bean的配置:
<bean id="methodCacheInterceptor" class="com.xiebing.utils.interceptor.MethodCacheInterceptor">
<property name="cache">
<ref local="demoCache" />
</property>
</bean>
<bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="methodCacheInterceptor" />
</property>
<property name="patterns">
<list>
<value>.*myMethod</value>
</list>
</property>
</bean>

<bean id="myServiceBean"
class="com.xiebing.ehcache.spring.MyServiceBean">
</bean>

<bean id="myService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="myServiceBean" />
</property>
<property name="interceptorNames">
<list>
<value>methodCachePointCut</value>
</list>
</property>
</bean>

其中myServiceBean是实现了业务逻辑的Bean,里面的方法myMethod()的返回结果需要被缓存。这样每次对myServiceBean的myMethod()方法进行调用,都会首先从缓存中查找,其次才会查询数据库。使用AOP的方式极大地提高了系统的灵活性,通过修改配置文件就可以实现对方法结果的缓存,所有的对Cache的操作都封装在了拦截器的实现中。

CachingFilter功能
使用Spring的AOP进行整合,可以灵活的对方法的的返回结果对象进行缓存。CachingFilter功能可以对HTTP响应的内容进行缓存。这种方式缓存数据的粒度比较粗,例如缓存整张页面。它的优点是使用简单、效率高,缺点是不够灵活,可重用程度不高。
EHCache使用SimplePageCachingFilter类实现Filter缓存。该类继承自CachingFilter,有默认产生cache key的calculateKey()方法,该方法使用HTTP请求的URI和查询条件来组成key。也可以自己实现一个Filter,同样继承CachingFilter类,然后覆写calculateKey()方法,生成自定义的key。
在笔者参与的项目中很多页面都使用AJAX,为保证JS请求的数据不被浏览器缓存,每次请求都会带有一个随机数参数i。如果使用SimplePageCachingFilter,那么每次生成的key都不一样,缓存就没有意义了。这种情况下,我们就会覆写calculateKey()方法。

要使用SimplePageCachingFilter,首先在配置文件ehcache.xml中,增加下面的配置:
<cache name="SimplePageCachingFilter" maxElementsInMemory="10000" eternal="false"
overflowToDisk="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU" />
其中name属性必须为SimplePageCachingFilter,修改web.xml文件,增加一个Filter的配置:
<filter>
<filter-name>SimplePageCachingFilter</filter-name>
<filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SimplePageCachingFilter</filter-name>
<url-pattern>/test.jsp</url-pattern>
</filter-mapping>

下面我们写一个简单的test.jsp文件进行测试,缓存后的页面每次刷新,在600秒内显示的时间都不会发生变化的。代码如下:
<%
out.println(new Date());
%>

CachingFilter输出的数据会根据浏览器发送的Accept-Encoding头信息进行Gzip压缩。经过笔者测试,Gzip压缩后的数据量是原来的1/4,速度是原来的4-5倍,所以缓存加上压缩,效果非常明显。
在使用Gzip压缩时,需注意两个问题:
1.
Filter在进行Gzip压缩时,采用系统默认编码,对于使用GBK编码的中文网页来说,需要将操作系统的语言设置为:zh_CN.GBK,否则会出现乱码的问题。
2. 默认情况下CachingFilter会根据浏览器发送的请求头部所包含的Accept-Encoding参数值来判断是否进行Gzip压缩。虽然IE6/7浏览器是支持Gzip压缩的,但是在发送请求的时候却不带该参数。为了对IE6/7也能进行Gzip压缩,可以通过继承CachingFilter,实现自己的Filter,然后在具体的实现中覆写方法acceptsGzipEncoding。

具体实现参考:
protected boolean acceptsGzipEncoding(HttpServletRequest request) {
final boolean ie6 = headerContains(request, "User-Agent", "MSIE 6.0");
final boolean ie7 = headerContains(request, "User-Agent", "MSIE 7.0");
return acceptsEncoding(request, "gzip") || ie6 || ie7;
}

EHCache在Hibernate中的使用
EHCache可以作为Hibernate的二级缓存使用。在hibernate.cfg.xml中需增加如下设置:
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
然后在Hibernate映射文件的每个需要Cache的Domain中,加入类似如下格式信息:
<cache usage="read-write|nonstrict-read-write|read-only" />
比如:
<cache usage="read-write" />
最后在配置文件ehcache.xml中增加一段cache的配置,其中name为该domain的类名。
<cache name="domain.class.name"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="false"
/>

EHCache的监控
对于Cache的使用,除了功能,在实际的系统运营过程中,我们会比较关注每个Cache对象占用的内存大小和Cache的命中率。有了这些数据,我们就可以对Cache的配置参数和系统的配置参数进行优化,使系统的性能达到最优。EHCache提供了方便的API供我们调用以获取监控数据,其中主要的方法有:

//得到缓存中的对象数
cache.getSize();
//得到缓存对象占用内存的大小
cache.getMemoryStoreSize();
//得到缓存读取的命中次数
cache.getStatistics().getCacheHits()
//得到缓存读取的错失次数
cache.getStatistics().getCacheMisses()

分布式缓存
EHCache从1.2版本开始支持分布式缓存。分布式缓存主要解决集群环境中不同的服务器间的数据的同步问题。具体的配置如下:

在配置文件ehcache.xml中加入
<cacheManagerPeerProvider
Factory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446"/>

<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>

另外,需要在每个cache属性中加入
<cacheEventListenerFactor
y class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
例如:
<cache name="demoCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="true">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
</cache>

总结
EHCache是一个非常优秀的基于Java的Cache实现。它简单、易用,而且功能齐全,并且非常容易与Spring、Hibernate等流行的开源框架进行整合。通过使用EHCache可以减少网站项目中数据库服务器的访问压力,提高网站的访问速度,改善用户的体验。

分享到:
评论
1 楼 zmwxiaoming 2016-11-22  

相关推荐

    ehcache的配置参数详解

    本文将深入探讨ehcache.xml配置文件中的关键参数及其作用,帮助开发者更有效地管理和优化缓存策略。 ### 1. `defaultCache` 标签 `defaultCache` 是ehcache.xml中一个重要的标签,用于定义所有未显式指定缓存策略...

    ehcache.xml

    本文将重点解析 Ehcache 的配置文件 `ehcache.xml` 及其核心方法,帮助开发者更好地理解和应用 Ehcache。 首先,我们来详细剖析 `ehcache.xml` 配置文件的各个部分: 1. **磁盘存储配置**:通过 `&lt;diskStore&gt;` ...

    ehcache-2.7.3-distribution.tar.gz

    描述中的"EHCache技术文档详解.doc"提示我们压缩包内包含了一份详细的技术文档,专门解释了EHCache的使用和功能,这将对理解和配置EHCache非常有帮助。 **标签"ehcache"** 标签"ehcache"是这个话题的核心,它是一...

    mybatis-ehcache-1.0.3.rar

    5. **示例代码或文档**:可能包含如何在项目中集成和配置MyBatis-Ehcache的示例或教程。 要使用MyBatis-Ehcache,你需要在MyBatis的配置文件中声明Ehcache作为缓存实现,并配置相应的Ehcache XML配置文件。在...

    Ehcache通过Jgroups做集群

    在`EhcacheClusterDemo`这个示例项目中,可能包含了配置文件和示例代码,用于展示如何使用Ehcache和Jgroups实现集群。可以深入研究这些示例,了解如何在实际项目中应用这些配置和代码。 集群配置对于大型分布式系统...

    hibernate整合ehcache的jar包.zip

    - **配置Hibernate**:在hibernate.cfg.xml或对应的配置文件中,启用二级缓存并指定使用Ehcache。 - **实体类注解**:在需要缓存的实体类上添加`@Cacheable`、`@Cache`等注解,定义缓存行为。 - **SessionFactory...

    mybatis-ehcache-1.0.3.zip

    3. **示例**:可能包含示例代码或项目,展示如何在实际应用中集成MyBatis-Ehcache,帮助开发者快速理解和使用。 4. **许可证文件**:通常会包含项目的许可证信息,定义了该软件的使用、修改和分发的法律条款。 ...

    spring+ehcache示例整合Demo

    首先,我们需要在项目的`pom.xml`文件中引入Ehcache和Spring的依赖。Ehcache通常使用的是`org.ehcache:ehcache`库,而Spring的相关依赖可能包括`spring-context`和`spring-context-support`,以支持缓存管理。 ```...

    ehcache缓存的jar包和配置文件

    下面将详细介绍Ehcache的核心概念、配置以及如何在项目中使用。 1. Ehcache核心概念: - 缓存:缓存是存储临时数据的地方,以便快速检索。Ehcache提供内存和磁盘存储,可以设置不同的缓存策略。 - 缓存管理器...

    ehcache-2.10.3-distribution.tar.gz

    1. **ehcache.xml**: 这是Ehcache的配置文件,用于定义缓存的行为和设置。开发者可以在这里指定缓存的大小、过期策略、缓存区域等参数。XML结构允许以结构化的方式配置复杂设置。 2. **ehcache.xsd**: 这是一个XML ...

    ehcache.zip

    总结来说,"ehcache.zip"提供了Ehcache的基本组件,包括库文件、配置示例、集成指南和配置文件的架构定义,为开发者提供了全面了解和使用Ehcache的资源。通过深入学习这些文件,开发者可以更好地掌握Ehcache的使用...

    ehcache使用详解

    Ehcache 是一个强大且灵活的缓存解决方案,通过合理的配置和使用,可以在Java应用中显著提升性能。了解其配置、原理以及如何在实际项目中应用,有助于我们更好地利用缓存机制,为用户提供更快速、更高效的体验。在...

    Ehcache缓存配置.doc

    然而,这个部分在提供的内容中未给出完整的配置示例,通常会包含如`rmiServerHost`、`rmiServerPort`等属性,以便Ehcache节点间相互通信。 总结来说,Ehcache的配置是其强大功能的关键,允许开发者根据应用需求定制...

    Ehcache(2): Ehcache实例在Eclipse中的配置 改进

    2. **配置Hibernate**:在Hibernate的配置文件`hibernate.cfg.xml`中,我们需要指定Ehcache作为二级缓存提供者。添加以下配置: ```xml &lt;property name="hibernate.cache.use_second_level_cache"&gt;true ...

    Ehcache2缓存区配置详解.pdf

    ### Ehcache2缓存区配置详解 #### 一、Ehcache概述 Ehcache,一个备受推崇的开源高速缓存系统,专为提升应用程序性能、减轻数据库负担及简化应用扩展设计。其卓越的稳定性和丰富的特性使其成为Java领域内最受欢迎...

    spring+ehcache完整示例demo

    3. **Spring配置**:在Spring的配置文件(如applicationContext.xml)中启用Ehcache支持,并加载上面的ehcache.xml配置。例如: ```xml &lt;bean id="cacheManager" class="org.springframework.cache.ehcache....

    shiro-demo使用ehcache做缓存.zip

    在这个“shiro-demo使用ehcache做缓存”的示例中,我们将深入探讨如何结合Apache Shiro和 Ehcache 实现高效的缓存管理。 Ehcache 是一个广泛使用的开源Java缓存解决方案,它提供了内存和磁盘存储,以及对缓存数据的...

    ehcache-1.2.2.jar

    2. 创建Ehcache配置文件(通常是ehcache.xml),定义缓存的属性,如大小、过期策略等。 3. 在代码中初始化Ehcache实例,并使用API进行缓存操作,如添加、获取、移除数据。 **使用示例** ```java import ...

    ehcache-2.10.5-distribution.tar.gz

    这个压缩包"ehcache-2.10.5-distribution.tar.gz"包含了该版本的所有必要组件,如API文档、核心库以及可能的示例和配置文件。 **Ehcache核心概念:** 1. **缓存**:Ehcache的核心是缓存,它存储临时数据以便快速...

Global site tag (gtag.js) - Google Analytics