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.csdn.net/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,通过!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值