`
hzjxy0624
  • 浏览: 12934 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

[转]EHCache的使用

阅读更多
在开发高并发量,高性能的网站应用系统时,缓存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);
}
}
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"
/>
http://www.uspcat.com/forum.php?mod=viewthread&tid=3987
分享到:
评论

相关推荐

    Ehcache分布式缓存入门案例demo_文件转树结构_

    本入门案例将带你了解如何使用Ehcache实现分布式缓存,并特别关注如何将文件数据转换为树形结构。 首先,让我们理解Ehcache的基本概念。Ehcache的核心组件包括缓存管理器(Cache Manager)、缓存(Cache)和缓存项...

    ehcache.xml

    Ehcache 是一个广泛使用的 Java 缓存框架,它提供了高效、灵活的内存和硬盘存储机制,能够显著提升应用程序的性能。本文将重点解析 Ehcache 的配置文件 `ehcache.xml` 及其核心方法,帮助开发者更好地理解和应用 ...

    jar包整合:Springmvc+hibernate+Ehcache+shior+mysql+Oracle+fastjson

    3. **Ehcache**:Ehcache是一个广泛使用的内存缓存系统,它可以提高应用程序的性能和响应速度。在Java应用中,Ehcache用于存储频繁访问的数据,减少数据库的访问压力,提供缓存管理策略,如LRU(最近最少使用)算法...

    Maven项目Spring4+Hibernate4+shiro+Ehcache项目集成

    5. **Ehcache**:Ehcache是一个广泛使用的内存缓存系统,可以提高应用程序的性能和响应速度。在本项目中,Ehcache可能用于缓存频繁查询的数据,如用户信息、角色信息等,以减少数据库的访问次数。 项目的集成过程...

    axis webservic ehcache.zip

    Ehcache则是一个广泛使用的Java缓存库,用于提高应用程序性能,通过存储经常访问的数据到内存中来减少数据库查询。 **Axis Web服务详解** Axis 是一个基于Java的Web服务工具包,允许开发者快速地创建、部署和管理...

    springmvc4+spring4+hibernate5.1.3+二级缓存ehcache+fastjson配置

    在IT领域,尤其是在Java Web开发中,`SpringMVC`、`Spring`、`Hibernate`以及`Ehcache`和`Fastjson`是常见的技术组件,它们分别在不同的层面上发挥着关键作用。以下是这些技术的详细介绍: 1. **SpringMVC**: ...

    Ehcache Java 缓存框架 v3.10.8.zip

    而“说明.htm”可能是官方文档的一部分,提供了关于如何配置、使用和优化Ehcache的详细指南。 在毕业设计或论文中,Ehcache可以作为研究缓存系统、性能优化或者分布式系统设计的案例。对于建站模板和系统软件工具,...

    hessian-3.0.20.jar,ehcache-1.2.3.jar,commons-codec-1.3.jar

    2. **Ehcache-1.2.3.jar**: Ehcache是一个广泛使用的Java缓存库,主要用于提升应用程序性能,通过存储常用数据来避免重复计算或从数据库中频繁读取。1.2.3是Ehcache的一个早期版本,尽管现在有更新的版本提供更多的...

    基于SpringBoot+Layui+shiro安全框架和Ehcache缓存框架搭建的学生管理系统源码+项目说明.zip

    但是我用ehcache缓存对list集合进行缓存时,layui的表格分页功能就会失效(比如我查询学生列表,并且对这个list添加了缓存,那么在前端展示时,layui的分页功能就会失效,转而显示所有的学生),目前还没有找到解决...

    ehcache-spring-dao:spring dao ehcache 集成示例

    首先,EHCache是一款广泛使用的开源Java分布式缓存系统,由Talend公司维护。它提供了一种高效、灵活的方式来存储和检索数据,避免了频繁的数据库查询,从而提高了应用的响应速度。EHCache支持内存和磁盘存储,可以...

    ehcache-spring-write-behind:实现 Ehcache + Spring 和 write behind 模式

    在这个秘籍中,您将看到如何在 Spring 3.1 及更高版本的最新缓存抽象 API 中使用内置的 EhCache 支持。 我们将使用基于注释的方法,但将遵循传统的 EhCache XML 配置。 使用 hsqldb 2.3.3 版本全面支持 JDBC 3.0 ...

    EhcacheTest

    【EhcacheTest】是一个项目,它展示了如何使用ANTLR库来构建一个解析器,将标准的SQL查询语言转换为Ehcache Search Query(EQL),这是Ehcache系统中的一个专用查询语言。ANTLR是一个强大的解析器生成器,它可以读取...

    SpringShiro分布式缓存版

    添加了使用ehcache的缓存机制 &lt;!-- securityManager --&gt; &lt;bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"&gt; &lt;property name="realm" ref="myRealm" /&gt; &lt;/bean&gt; ...

    ehcache.zip_matlab例程_Java_

    "matlab例程"提示该文件可能包含了使用MATLAB编写的示例代码或程序,而"Java"则意味着这些示例可能涉及到Java编程语言,可能是为了在Java环境中使用ehcache缓存系统。 描述提到"这是一个ehcache的jar包,喜欢的话...

    spring+springmvc+mybatis项目案例实现用户角色权限管理

    整合EhCache,对Mybatis的二级缓存进行管理和对spring进行缓存管理 整合FastJson对指定http类型的数据进行转换 整合hibernate.validator校验器对controller接口参数进行校验 使用了springmvc统一异常处理 使用了...

    应用级产品开发平台APDPlat.zip

    18)、缓存使用EhCache或是Memcached。 19)、数据库连接池使用CommonsDBCP。 20)、Office文档操作使用POI。 21)、工作流使用Activiti。 22)、报表使用BIRT。 23)、Web资源优化使用wro4j。 24)、日志拦截使用...

    hibernate转换编码配置和权限及java代码

    对于Hibernate本身,它支持二级缓存,通过集成如EHCache或Infinispan等缓存系统,可以缓存查询结果,减少对数据库的访问。二级缓存分为集合缓存和实体缓存,集合缓存用于缓存关联集合,而实体缓存则缓存单个持久化...

    分布式缓存.docx

    Ehcache还允许通过RMI进行分布式缓存,虽然使用较少,但在特定场景下仍有一定的价值。Ehcache的主要特性包括快速响应、简单的API、丰富的缓存策略、自动持久化等。在Hibernate和Spring等框架中,Ehcache常作为默认的...

    ENCACHE缓存简介

    在实际使用Ehcache时,开发人员通常会借助`EHCacheUtil`这样的工具类来操作缓存,如`put(key, value)`方法用于添加缓存,`get(key)`方法用于获取缓存。此外,`ehcache.xml`配置文件用于定义缓存的详细设置,如大小、...

Global site tag (gtag.js) - Google Analytics