java缓存实现与spring托管.docx
- 文档编号:3507361
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:28
- 大小:271.22KB
java缓存实现与spring托管.docx
《java缓存实现与spring托管.docx》由会员分享,可在线阅读,更多相关《java缓存实现与spring托管.docx(28页珍藏版)》请在冰豆网上搜索。
java缓存实现与spring托管
目录
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.1EHCache的类层次模型5
2.2环境搭建6
2.3ehcache配置文件中元素说明8
2.4在工程中单独使用10
3.在Spring中运用EHCache17
4.分布式缓存集群环境配置19
4.1集群配置方式19
5.测试用例28
0.文档介绍
0.1文档目的
记录使用EHCache实现页面级的缓存以及完成集群设计的过程。
0.2文档范围
记录使用EHCache实现页面级的缓存以及完成集群设计的过程。
0.3读者对象
任何有兴趣的家伙。
0.4参考文献
提示:
列出本文档的所有参考文献(可以是非正式出版物),格式如下:
[标识符]作者,文献名称,出版单位(或归属单位),日期
大部分都是网络上查询的资料,很多,不列举了。
EHCache简介:
Spring整合EHCache:
0.5术语与缩写解释
缩写、术语
解释
EHCache
EHCache是一个快速的、轻量级的、易于使用的、进程内的缓存。
它支持read-only和read/write缓存,内存和磁盘缓存。
是一个非常轻量级的缓存实现,而且从1.2之后就支持了集群,目前的最新版本是2.1。
…
1.概述
1.1背景
系统缓存是位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域,目的是为了减少应用程序对物理数据源访问的次数,从而提高应用程序的运行性能.缓存设想内存是有限的,缓存的时效性也是有限的,所以可以设定内存数量的大小,可以执行失效算法,可以在内存满了的时候,按照最少访问等算法将缓存直接移除或切换到硬盘上。
Ehcache从Hibernate发展而来,逐渐涵盖了Cahce界的全部功能,是目前发展势头最好的一个项目。
具有快速,简单,低消耗,依赖性小,扩展性强,支持对象或序列化缓存,支持缓存或元素的失效,提供LRU、LFU和FIFO缓存策略,支持内存缓存和磁盘缓存,分布式缓存机制等等特点。
Cache存储方式:
内存或磁盘。
官方网站:
1.2主要特性
1.快速.
2.简单.
3.多种缓存策略
4.缓存数据有两级:
内存和磁盘,因此无需担心容量问题
5.缓存数据会在虚拟机重启的过程中写入磁盘
6.可以通过RMI、可插入API等方式进行分布式缓存
7.具有缓存和缓存管理器的侦听接口
8.支持多缓存管理器实例,以及一个实例的多个缓存区域
9.提供Hibernate的缓存实现
1.3环境
WindowsXP、JDK1.6.03、Tomcat5.5、EHcache2.1
注意:
配置好环境变量。
1.4下载资源
ehcache-2.1.0-distribution.tar.gz:
以及ehcache-web-2.0.2-distribution.tar.gz
注意:
同时要下载源代码,部分功能需要修改源代码,重新做包。
2.EHCache页面缓存的配置
2.1EHCache的类层次模型
主要为三层,最上层的是CacheManager,他是操作Ehcache的入口。
我们可以通过CacheManager.getInstance()获得一个单子的CacheManger,或者通过CacheManger的构造函数创建 一个新的CacheManger。
每个CacheManager都管理着多个Cache。
而每个Cache都以一种类Hash的方式,关联着多个Element。
Element则是我们用于存放要缓存内容的地方。
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.3ehcache配置文件中元素说明
ehcach.xml配置文件主要参数的解释,其实文件里有详细的英文注释//DiskStore配置,cache文件的存放目录,主要的值有
*user.home-用户主目录
*user.dir-用户当前的工作目录
*java.io.tmpdir-Defaulttempfilepath默认的temp文件目录
范例
1、首先设置EhCache,建立配置文件ehcache.XML,默认的位置在class-path,可以放到你的src目录下:
<?
xmlversion="1.0"encoding="UTF-8"?
>
<ehcache>
<diskStorepath="Java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"<!
-缓存最大数目->
eternal="false"<!
-缓存是否持久->
overflowToDisk="true"<!
-是否保存到磁盘,当系统当机时->
timeToIdleSeconds="300"<!
-当缓存闲置n秒后销毁->
timeToLiveSeconds="180"<!
-当缓存存活n秒后销毁->
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"/>
</ehcache>
了解ehcache的几个概念,
1timeToIdleSeconds,多长时间不访问该缓存,那么ehcache就会清除该缓存。
2timeToLiveSeconds,缓存的存活时间,从开始创建的时间算起。
Ehcache的三种清空策略
1FIFO,firstinfirstout,这个是大家最熟的,先进先出。
2LFU,LessFrequentlyUsed,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。
如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
3LRU,LeastRecentlyUsed,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
首页的页面缓存
一个网站的首页估计是被访问的次数最多的,我们可以考虑给首页做一个页面缓存
缓存策略:
我认为应该是某个固定时间之内不变的,比如说2分钟更新一次,以应用结构page-filter-action-service-dao-db为例。
位置:
页面缓存做到尽量靠近客户的地方,就是在page和filter之间,这样的优点就是第一个用户请求之后,页面被缓存,第二个用户再来请求的时候,走到filter这个请求就结束了,无需再走后面的action-service-dao-db。
带来的好处是服务器压力的减低和客户段页面响应速度的加快。
首页的页面缓存的存活时间,我们定的是2分钟,那么也就是说我们的timeToLiveSeconds应该设置为120,同时我们的timeToIdleSeconds最好也设置为2分钟,或者小于2分钟。
我们来看一下下面这个配置,这个配置片段应该放到ehcache.xml中:
SimplePageCachingFilter是缓存的名字,maxElementsInMemory表示内存中SimplePageCachingFilter缓存中元素的最大数量为10,maxElementsOnDisk是指持久化该缓存的元素到硬盘上的最大数量也为10(),eternal=false意味着该缓存会死亡。
overflowToDisk=true意思是表示当缓存中元素的数量超过限制时,就把这些元素持久化到硬盘,如果overflowToDisk是false,那么maxElementsOnDisk的设置就没有什么意义了。
memoryStoreEvictionPolicy=LFU是指按照缓存的hit值来清除,也就是说缓存满了之后,新的对象需要缓存时,将会将缓存中hit值最小的对象清除出缓存,给新的对象腾出地方来了。
接着我们来看一下SimplePageCachingFilter的配置,
XML/HTML代码
net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter
就只需要这么多步骤,我们就可以给某个页面做一个缓存的,把上面这段配置放到你的web.xml中,那么当你打开首页的时候,你会发现,2分钟才会有一堆sql语句出现在控制台上。
当然你也可以调成5分钟,总之一切都在控制中。
好了,缓存整个页面看上去是非常的简单,甚至都不需要写一行代码,只需要几行配置就行了,够简单吧,虽然看上去简单,但是事实上内部实现却不简单哦,有兴趣的话,大家可以看看SimplePageCachingFilter继承体系的源代码。
上面的配置针对的情况是缓存首页的全部,如果你只想缓存首页的部分内容时,你需要使用SimplePageFragmentCachingFilter这个filter。
我们看一下如下片断:
XML/HTML代码
net.sf.ehcache.constructs.web.filter.SimplePageFragmentCachingFilter
filter>
这个jsp需要被jsp:
include到其他页面,这样就做到的局部页面的缓存。
这一点貌似没有oscache的tag好用。
事实上在cachefilter中还有一个特性,就是gzip,也就是说缓存中的元素是被压缩过的,如果客户浏览器支持压缩的话,filter会直接返回压缩过的流,这样节省了带宽,把解压的工作交给了客户浏览器,如果客户的浏览器不支持gzip,那么filter会把缓存的元素拿出来解压后再返回给客户浏览器(大多数爬虫是不支持gzip的,所以filter也会解压后再返回流),这样做的优点是节省带宽,缺点就是增加了客户浏览器的负担(但是我觉得对当代的计算机而言,这个负担微乎其微)。
好了,如果你的页面正好也需要用到页面缓存,不防可以考虑一下ehcache,因为它实在是非常简单,而且易用。
总结:
ehcache是一个非常轻量级的缓存实现,而且从1.2之后就支持了集群,目前的最新版本是1.3,而且是hibernate默认的缓存provider。
虽然本文是介绍的是ehcache对页面缓存的支持,但是ehcache的功能远不止如此,当然要使用好缓存,对JEE中缓存的原理,使用范围,适用场景等等都需要有比较深刻的理解,这样才能用好缓存,用对缓存。
最后复习一下ehcache中缓存的3种清空策略:
1FIFO,firstinfirstout,这个是大家最熟的,先进先出,不多讲了
2LFU,LessFrequentlyUsed,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。
如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
2LRU,LeastRecentlyUsed,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
2.4在工程中单独使用
1.创建CacheManager(net.sf.ehcache.CacheManager)
(1)使用默认配置文件创建
CacheManagermanager=CacheManager.create();
(2)使用指定配置文件创建
CacheManagermanager=CacheManager.create("src/config/ehcache.xml");
(3)从classpath找寻配置文件并创建
URLurl=getClass().getResource("/anothername.xml");
CacheManagermanager=CacheManager.create(url);
(4)通过输入流创建
InputStreamfis=newFileInputStream(newFile("src/config/ehcache.xml").getAbsolutePath());
try{manager=CacheManager.create(fis);}finally{fis.close();}
2.创建Caches(net.sf.ehcache.Cache)
(1)取得配置文件中预先定义的sampleCache1设置,生成一个Cache
Cachecache=manager.getCache("sampleCache1");
(2)设置一个名为test的新cache,test属性为默认
CacheManagermanager=CacheManager.create();
manager.addCache("test");
(3)设置一个名为test的新cache,并定义其属性
CacheManagermanager=CacheManager.create();
Cachecache=newCache("test",1,true,false,5,2);
manager.addCache(cache);
(4)删除cache
CacheManagersingletonManager=CacheManager.create();
singletonManager.removeCache("sampleCache1");
3.使用Caches
(1)往cache中加入元素
Elementelement=newElement("key1","value1");
cache.put(newElement(element);
(2)从cache中取得元素
Elementelement=cache.get("key1");
(3)从cache中删除元素
Cachecache=manager.getCache("sampleCache1");
Elementelement=newElement("key1","value1");
cache.remove("key1");
3.卸载CacheManager,关闭Cache
manager.shutdown();
3.在Spring中运用EHCache
需要使用Spring来实现一个Cache简单的解决方案,具体需求如下:
使用任意一个现有开源CacheFramework,要求可以Cache系统中Service或则DAO层的get/find等方法返回结果,如果数据更新(使用Create/update/delete方法),则刷新cache中相应的内容。
根据需求,计划使用SpringAOP+ehCache来实现这个功能,采用ehCache原因之一是Spring提供了ehCache的支持,至于为何仅仅支持ehCache而不支持osCache和JBossCache无从得知(Hibernate?
?
?
),但毕竟Spring提供了支持,可以减少一部分工作量:
)。
二是后来实现了OSCache和JBossCache的方式后,经过简单测试发现几个Cache在效率上没有太大的区别(不考虑集群),决定采用ehCahce。
AOP嘛,少不了拦截器,先创建一个实现了MethodInterceptor接口的拦截器,用来拦截Service/DAO的方法调用,拦截到方法后,搜索该方法的结果在cache中是否存在,如果存在,返回cache中的缓存结果,如果不存在,返回查询数据库的结果,并将结果缓存到cache中。
MethodCacheInterceptor.java
Java代码
packagecom.co.cache.ehcache;
importjava.io.Serializable;
importnet.sf.ehcache.Cache;
importnet.sf.ehcache.Element;
importorg.aopalliance.intercept.MethodInterceptor;
importorg.aopalliance.intercept.MethodInvocation;
importmons.logging.Log;
importmons.logging.LogFactory;
importorg.springframework.beans.factory.InitializingBean;
importorg.springframework.util.Assert;
publicclassMethodCacheInterceptorimplementsMethodInterceptor,InitializingBean
{
privatestaticfinalLoglogger=LogFactory.getLog(MethodCacheInterceptor.class);
privateCachecache;
publicvoidsetCache(Cachecache){
this.cache=cache;
}
publicMethodCacheInterceptor(){
super();
}
/**
*拦截Service/DAO的方法,并查找该结果是否存在,如果存在就返回cache中的值,
*否则,返回数据库查询结果,并将查询结果放入cache
*/
publicObjectinvoke(MethodInvocationinvocation)throwsThrowable{
StringtargetName=invocation.getThis().getClass().getName();
StringmethodName=invocation.getMethod().getName();
Object[]arguments=invocation.getArguments();
Objectresult;
logger.debug("Findobjectfromcacheis"+cache.getName());
StringcacheKey=getCacheKey(targetName,methodName,arguments);
Elementelement=cache.get(cacheKey);
if(element==null){
logger.debug("Holdupmethod,Getmethodresultandcreatecache........!
");
result=invocation.proceed();
element=newElement(cacheKey,(Serializable)result);
cache.put(element);
}
returnelement.getValue();
}
/**
*获得cachekey的方法,cachekey是Cache中一个Element的唯一标识
*cachekey包括包名+类名+方法名,如com.co.cache.service.UserServiceImpl.getAllUser
*/
privateStringgetCacheKey(StringtargetName,StringmethodName,Object[]arguments){
StringBuffer
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 缓存 实现 spring 托管