Ehcache 页面缓存

       web项目中想在tomcat启动加载web时,就自动缓存上数据库中的某些“公用大数据”,减少对数据库的频繁访问,想通过Ehcache实现缓存,tomcat启动时的自加载用监听器来实现。

首先介绍下Ehcache

      Ehcache是来sourceforge(http://ehcache.sourceforge.net/)的开源项目,是纯Java实现的简单、快速的Cache组件。可以对页面、对象、数据进行缓存,支持集群/分布式缓存。如果整合Spring、Hibernate也非常的简单,Spring对Ehcache的支持也非常好。EHCache支持内存和磁盘的缓存,支持LRU、LFU和FIFO多种淘汰算法,支持分布式的Cache,可以作为Hibernate的缓存插件。同时它也能提供基于Filter的Cache,该Filter可以缓存响应的内容并采用Gzip压缩提高响应速度。使用S2SH开发网站,网站首页需要展示的数据多,访问量大。如果不做处理,则频繁的查询数据库,结果是页面显示的慢,服务器、数据库不堪重负。如果网站页面所展示的数据的更新不是特别频繁,想提高页面显示的速度,减轻服务器的负担,此时应该考虑使用缓存。   

关于ehcache的缓存配置可参照Ehcache缓存配置ehcache的创建和使用参照 http://sishuok.com/forum/posts/list/315.html。


网上关于ehcache的资料好多都是ehcache的一个实例module,即页面缓存,考虑到项目相关性,及了解ehcache原理的目的,尝试实现这个页面缓存。

过程很曲折,但都一一解决,现在梳理下整个步骤:

   Tomcat 的webapps下新建个test目录,再建一个WEB-INF、WEB-INF/lib、WEB-INF/classes目录;

   下载最新的ehcache-web包,然后将包中的ehcache-web-2.0.4.jar、ehcache-core-2.4.6.jar、slf4j-api-1.6.1.jar放入lib目录中;(注意,这三个包一个不能少!!!)

    配置web.xml

 

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

	<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>
	
	
	<welcome-file-list>     
		<welcome-file>test.jsp</welcome-file>  
	</welcome-file-list>  

</web-app>

使用SimplePageCachingFilter过滤类(继承CachingFilter)来实现对名为SimplePageCachingFilter的过滤器,这个过滤器拦截/test.jsp页面请求,也就是对该页面进行缓存。


   配置ehcache.xml
,这个文件要放到src目录下(编译后会在classes目录下)!

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">

<cache name="SimplePageCachingFilter" maxElementsInMemory="10000" eternal="false"
	overflowToDisk="false" timeToIdleSeconds="300" timeToLiveSeconds="60"
	memoryStoreEvictionPolicy="LFU" />

</ehcache>

该缓存的有效生存时间是60秒,60秒后缓存失效,但不重新读,直到再有该页面请求,才重新读取到缓存中。

    测试:test.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<HTML>
	<HEAD>
		<title>test</title>
		<meta http-equiv="Content-Type" content="text/html; charset=gbk">
		
	<%
		Date d=new Date();
		System.out.println("execute test.jsp:"+d);
		out.println(d);
	%>	
	</HEAD>
	<body>
		
	</body>
</HTML>

该页面打印出页面被请求时的时间。

第一次访问test.jsp后的1分钟内,再次访问时的界面是不变,即tomcat返回的是缓存中的test.jsp。一分钟后再次访问时“tomcat”(通过SimplePageCachingFilter过滤器)重新读取test.jsp并放入缓存。tomcat输出结果为:



以上内容还参考了:

ehcache介绍  http://raychase.iteye.com/blog/1545906 

http://blog.youkuaiyun.com/jingmaoxiaoqiang/article/details/9737647

http://blog.sina.com.cn/s/blog_46d5caa40100ka9z.html

http://blog.sina.com.cn/s/blog_56fd58ab0100w0pl.html

jsp从数据库取数据  http://happysoul.iteye.com/blog/1151692


补充:

   上面的结果都是在一台电脑上的运行结果,尝试在不同电脑的缓存是否一致:

           在自己电脑上输入  http://localhost:8080/test/test.jsp运行显示了   时间1;立即在另一台电脑上输入http://localhost:8080/test,(web.xml配置了主页为test.jsp)结果显示的却是 时间2,大惊!!  难道不同电脑的对同一页面请求后,会有不同的缓存?  也就是说服务器对每台电脑进行缓存页面,而不是指缓存一个,那这对我没任何帮助啊!  关键是演示的时候,老师在看,之前口口声声说解决了,现在出问题了,那我就囧大了!  幸好老师好像没看出来,老师走后,理解找问题点。

   通过查网上资料:“CachingFilter功能可以对HTTP响应的内容进行缓存。这种方式缓存数据的粒度比较粗,例如缓存整张页面。它的优点是使用简单、效率高,缺点是不够灵活,可重用程度不高。EHCache使用SimplePageCachingFilter类实现Filter缓存。该类继承自CachingFilter,有默认产生cache key的calculateKey()方法,该方法使用HTTP请求的URI和查询条件来组成key。也可以自己实现一个Filter,同样继承CachingFilter类,然后覆写calculateKey()方法,生成自定义的key。” (摘自 http://www.cnblogs.com/hoojo/archive/2012/07/12/2587556.html) 。 

   疑问: 难道SimplePageCachingFilter利用calculateKey()计算key时的请求URI 包括请求主机的地址? 要是这样的话,那我岂不是要重写一个过滤器类,该类继承SimplePageCachingFilter,但覆盖其calculateKey()方法?


    偶然发现刚才的两个URL不完全相同的,虽然最后请求的都是test.jsp。继续尝试:在不同电脑上分别打开两个窗口,并分别输入http://<ip>8080/test/test.jsp和http://<ip>8080/test,发现对于/test/test.jsp的页面的缓存是同一个,而/test的缓存是另外一个,用不同浏览器观察到的结果也符合。也就是说/test/test.jsp和/test的缓存是不一样的(Element),因为他们的URI不一样,所以计算出的key也不一样,因此element缓存条也不同!!!


     还好,虚惊一场!   但以后要是真的要缓存主页,并且web.xml配置了主页,那如何解决这个问题呢?  还得是自己写个继承SimplePageCachingFilter的过滤类,然后覆盖calculateKey()方法;或者干脆写个虚的主页,这个主页做一个跳转,跳转到真正的主页(test.jsp).


     在虚拟机里(jdk7+tomcat7)里加上了读取数据库,好使之后,尝试将该web放到添加到自己项目中(项目是用方正FIX BPMES平台开发,该平台用的是JDK5+tomcat5),结果提示“UnsupportedClassVersionError: Bad version number in .class file”,网上说是class类不兼容,我用eclipse改变编译jdk5,把连接数据库的class替换,但仍然不好使; 然后我直接在jsp里连接数据库,运行仍然提示刚才的问题,各种尝试,纠结了一晚上。网上搜tomcat5下连接数据库,没有用价值。终于搜jsp连接mssql2008时,看到有文章说“jdk6以后的jdbc包要用sqljdbc4.jar 包, 之前版本的JDK的用 sqljdbc.jar 包”,原来如此!   网上下载sqljdbc.jar,替换sqljdbc4.jar,通过!


本工程用于研究如何借助Ehcache缓存框架实现对页面缓存 本工程编码方式:UTF-8 本工程开发工具:MyEclipse 说明: 1、ehcache.xml和ehcache.xsd两个文件可以在下在下载下来的名为“ehcache-core-x.x.x-distribution.tar.gz”压缩文件中找到 2、由于要实现Ehcache缓存页面,所以必须要添加“ehcache-web-2.0.4.jar” jar包,该jar包主要用于辅助Ehcache实现页面缓存 注意: 本web工程的发布不要使用Tomcat7,否则会出现如下异常: 2015-3-25 9:53:50 org.apache.catalina.loader.WebappClassLoader loadClass 信息: Illegal access: this web application instance has been stopped already. Could not load net.sf.ehcache.store.disk.DiskStore$KeySet. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact. java.lang.IllegalStateException at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559) at net.sf.ehcache.store.disk.DiskStore.keySet(DiskStore.java:560) at net.sf.ehcache.store.disk.DiskStorageFactory$DiskExpiryTask.run(DiskStorageFactory.java:838) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) 相关jar包下载地址: Ehcache 对象、数据缓存:http://ehcache.org/downloads/destination?name=ehcache-core-2.5.2-distribution.tar.gz&bucket=tcdistributions&file=ehcache
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值