EHCache 是一个纯java的在进程中的缓存,它具有下面特性:高速,简单,为Hibernate2.1充当可插入的缓存,最小的依赖性,全面的文档和測试.官方站点http://ehcache.sourceforge.net/
毫无疑问,差点儿全部的站点的首页都是訪问率最高的,而首页上的数据来源又是很广泛的,大多数来自不同的对象,并且有可能来自不同的db ,所以给首页做缓存是一个不错的主意,那么主页的缓存策略是什么样子的呢,我觉得应该是某个固定时间之内不变的,比方说2 分钟更新一次.那么这个缓存应该做在什么地方呢,让我们来看一下,如果您的应用的结构是page-filter-action-service-dao-db ,这个过程中的- 的地方都是能够做缓存的地方,依据页面缓存的特征,应该把页面缓存做到尽量靠近客户的地方,就是在page
和filter 之间,这种优点就是第一个用户请求之后,页面被缓存,第二个用户再来请求的时候,走到filter 这个请求就结束了,无需再走后面的action-service-dao-db .带来的优点是server压力的减低和客户段页面响应速度的加快.
那么我们来看一下怎样使用ehcache 做到这一点.
在使用ehcache 的页面缓存之前,我们必需要了解ehcache 的几个概念,
1 timeToIdleSeconds ,多长时间不訪问该缓存,那么ehcache 就会清除该缓存.
2 timeToLiveSeconds ,缓存的存活时间,从開始创建的时间算起.
首页的页面缓存的存活时间,我们定的是2 分钟,timeToLiveSeconds 应该设置为120 ,同一时候我们的timeToIdleSeconds 最好也设置为2 分钟,或者小于2 分钟.我们来看一下以下这个配置,这个配置片段应该放到ehcache.xml 中:
<cache name= "SimplePageCachingFilter"
maxElementsInMemory = "10"
maxElementsOnDisk = "10"
eternal = "false"
overflowToDisk = "true"
diskSpoolBufferSizeMB = "20"
timeToIdleSeconds = "10"
timeToLiveSeconds = "10"
memoryStoreEvictionPolicy = "LFU"
/>
SimplePageCachingFilter 是缓存的名字,maxElementsInMemory 表示内存中SimplePageCachingFilter 缓存中元素的最大数量为10 ,maxElementsOnDisk 是指持久化该缓存的元素到硬盘上的最大数量也为10 ,eternal=false 意味着该缓存会死亡.overflowToDisk=true 意思是表示当缓存中元素的数量超过限制时,就把这些元素持久化到硬盘,假设overflowToDisk 是false ,那么maxElementsOnDisk
的设置就没有什么意义了.memoryStoreEvictionPolicy=LFU 是指依照缓存的hit 值来清除,也就是说缓存满了之后,新的对象须要缓存时,将会将缓存中hit 值最小的对象清除出缓存,给新的对象腾出地方来了(文章最后有ehcache 中自带的3 种缓存清空策略的介绍).
SimplePageCachingFilter 的配置,
<filter>
<filter-name> indexCacheFilter </filter-name>
<filter-class>
net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name> indexCacheFilter </filter-name>
<url-pattern> *index.action </url-pattern>
</filter-mapping>
就仅仅须要这么多步骤,我们就能够给某个页面做一个缓存的,把上面这段配置放到你的web.xml 中,那么当你打开首页的时候,你会发现,2 分钟才会有一堆sql 语句出如今控制台上.当然你也能够调成5 分钟,总之中的一个切都在控制中.
好了,缓存整个页面看上去是很的简单,甚至都不须要写一行代码,仅仅须要几行配置即可了,够简单吧,尽管看上去简单,可是其实内部实现却不简单哦,有兴趣的话,大家能够看看SimplePageCachingFilter 继承体系的源码.
上面的配置针对的情况是缓存首页的所有,假设你仅仅想缓存首页的部分内容时,你须要使用SimplePageFragmentCachingFilter 这个filter .我们看一下例如以下片断:
<filter>
<filter-name> indexCacheFilter </filter-name>
<filter-class>
net.sf.ehcache.constructs.web.filter.SimplePageFragmentCachingFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name> indexCacheFilter filter-name>
<url-pattern> */index_right.jsp </url-pattern>
</filter-mapping >
这个jsp 须要被jsp:include 到其它页面,这样就做到的局部页面的缓存.这一点貌似没有oscache 的tag 好用.
其实在cachefilter 中另一个特性,就是gzip ,也就是说缓存中的元素是被压缩过的,假设客户浏览器支持压缩的话,filter 会直接返回压缩过的流,这样节省了带宽,把解压的工作交给了客户浏览器,假设客户的浏览器不支持gzip ,那么filter 会把缓存的元素拿出来解压后再返回给客户浏览器(大多数爬虫是不支持gzip 的,所以filter 也会解压后再返回流),这样做的长处是节省带宽,缺点就是添加了客户浏览器的负担(可是我认为对当代的计算机而言,这个负担微乎其微).
好了,假设你的页面正好也须要用到页面缓存,不防能够考虑一下ehcache ,由于它实在是很easy,并且易用.
总结:ehcache 是一个很轻量级的缓存实现,并且从1.2 之后就支持了集群,眼下的最新版本号是1.3 ,并且是hibernate 默认的缓存provider .尽管本文是介绍的是ehcache 对页面缓存的支持,可是ehcache 的功能远不止如此,当然要使用好缓存,对JEE 中缓存的原理,使用范围,适用场景等等都须要有比較深刻的理解,这样才干用好缓存,用对缓存.
ehcache 中缓存的3 种清空策略:
1 FIFO ,first in first out ,这个是大家最熟的,先进先出,不多讲了
2 LFU , Less Frequently Used ,就是上面样例中使用的策略,直白一点就是讲一直以来最少被使用的.如上面所讲,缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存.
2 LRU ,Least Recently Used ,近期最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又须要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存.
简单介绍
Ehcache俩中缓存机制:
· MemoryStore(内存存储)
· DiskStore(磁盘存储)
MemoryStore
MemoryStore总是可用的,但不可直接操作,其中存储着全部的Cache.
· 合适的Element类型
全部的Element都能够放在MemoryStore中.
· 安全性:使用多个线程并行检查内存泄露.
· JDK:使用了JDK1.5的LinkedHashMap来存放Elemen.t
· 高速的:是最快的缓存机制,由于它是存放在内存中.
· 失效策略(Memory)
Cache 能够配置最大缓存Element的个数,以及失效时间.假设在加入Elemtent时,缓存中的Element个数达到了最大缓存数而且 overflowToDisk配置的属性为true,Ehcache会更具配置项MemoryStoreEvictionPolicy的失效策略将 Element输出到磁盘.假设overflowToDisk为fasle,Ehcache将删除内存中Element.Ehcache支持三种失效策略:LRU,LFU,FIFO.
值得注意的是缓存中失效的Element并不会别立即清理掉,所以想得到内存的真实大小应该调用方法calculateInMemorySize()方法.
DiskStore
DiskStore可缓存到外部设备上(硬盘).
· DiskStores are Optional
Ehcache从1.5版本号開始支持DiskStore.假设你须要多个DiskStore的话,最好给他们配置不同的文件路径.
· 关闭磁盘缓存:仅仅要凝视掉ehcache.xml配置文件里的磁盘缓存配置项就可以.而ehcache-failsafe.xml的磁盘缓存配置不会影响到你自己的cache.
· 合适的Element类型
这里要注意要想使用磁盘缓存,缓存的Element必须实现序列化接口.否则会抛出NotSerializableException异常.
· 存储:Ehcache会将每一个缓存配置的文件路径下创建一个cache_name.data文件,假设使用的磁盘持久化技术,还会生成一个cache name.index文件.
· 失效
Ehcache有一个后台线程专门做Ellment失效监測以及清除工作.设置线程执行间隔时间,可通过设置diskExpiryThreadIntervalSeconds属性来完毕,此值不宜设置过低,否则会导致清理线程占用大量CPU资源.默认值是120秒.
· 持久化
持久化可在Element的diskPersistent配置项中配置,假设配置为"false"或是"omitted"在CacheManager shutdown或是startup后,用来缓存Element的文件将被清除掉.假设设置为"true",data和index文件会被保存下来,对于新创建的CacheManager Element也是可用的.
使用时必须显示调用cache. Flush()才会将数据缓存到磁盘中.
磁盘缓存步骤:从MemoryStore中把没有失效的Element刷新到DiskStore,Element被写入到data文件,Element将被序列化到index文件.
Ehcache缓存回收策略
缓存回收就是当缓存满了的时候,Ehcache会依据指定的策略来清理缓存.这里的缓存回收策略有别与Ehcache中的失效清理策略.失效清理策略是对失效的Element进行批量清理时所採用的策略,终于全部失效的Element都将被清理,仅仅只是是清理的先后顺序不同罢了.Ehcache中缓存的最大 Element数是由maxElementsInMemory来指定的.当缓存中的Element个数达到maxElementsInMemory指定的值时,Ehcache会依据详细的策略来清理缓存,默认的策略是LRU(近期最少使用).
磁盘缓存大小默认是没有限制的,只是可通过maxElementsOnDisk来指定.当磁盘缓存达到maxElementsOnDisk指定的值时,Ehcache会清理磁盘中的缓存使用默认策略是LFU(使用频率最低).
Make sure you are using a supported Java version.
Place the Ehcache jar into your classpath.
Ensure that any libraries required to satisfy dependencies are also in the classpath.
Configure ehcache.xml and place it in your classpath.
Optionally, configure an appropriate logging level.
xxxx
Downloads: http://sourceforge.net/projects/ehcache/files/
Welcome to ehcache:http://ehcache.org/