ehcache实现页面整体缓存和页面局部缓存
之前写过spring cache和ehcache的基本介绍和注解实现缓存管理,今天记录下web项目的页面缓存技术。
页面缓存是否有必要?。
这样说吧,几乎所有的网站的首页都是访问率最高的,而首页上的数据来源又是非常广泛的,大多数来自不同的对象,而且有可能来自不同的db ,所以给首页做缓存是很必要的。那么主页的缓存策略应该怎样设计呢?我认为应该是某个固定时间之内不变的,比如说2分钟更新一次。那么这个缓存应该做在什么地方呢?让我们来看一下,当前我们的的应用的结构一般是是page-filter-action-service-dao-db ,这个过程中的- 的地方都是可以做缓存的地方,根据页面缓存的特征,应该把页面缓存做到尽量靠近客户的地方,就是在page 和filter 之间,这样的优点就是第一个用户请求之后,页面被缓存,第二个用户再来请求的时候,走到filter 这个请求就结束了,无需再走后面的action-service-dao-db 。带来的好处是服务器压力的减低和客户段页面响应速度的加快。了解了这些之后我们开始介绍重点。
ehcache页面缓存的特点:缓存中的元素是被压缩过的,如果客户浏览器支持压缩的话,filter 会直接返回压缩过的流,这样节省了带宽,把解压的工作交给了客户浏览器,如果客户的浏览器不支持gzip ,那么filter 会把缓存的元素拿出来解压后再返回给客户浏览器(大多数爬虫是不支持gzip 的,所以filter 也会解压后再返回流),这样做的优点是节省带宽,缺点就是增加了客户浏览器的负担
1 .SimplePageCachingFilter
它ehcache-web模块下页面缓存Filter的一个简单实现,适用于可以压缩的Http响应(response),如HTML、XML、JSON等。它会使用通过CacheManager的静态方法create创建的单例CacheManager,这样如果之前已经存在CacheManager的实例了的话,这里就会直接拿来用,而不会再创建了。所以这里一般默认情况下会取类根路径下的ehcache.xml文件来创建CacheManager,但如果我们的项目中整合了Ehcache和Spring,且在Spring配置文件中指定的Ehcache的配置文件不是默认位置的话,Spring将使用指定的配置文件优先初始化CacheManager,这样SimplePageCachingFilter中要使用CacheManager时就不会再初始化了,而是直接使用Spring初始化的。页面缓存使用的key是通过SimplePageCachingFilter的calculateKey()方法获取的。其内部逻辑是获取请求时的URI及后面的查询字符串作为key进行返回,如“/user/index.jsp?name=abc”,这使得它的应用范围非常广。它不依赖于主机名和端口号,这将使得它同样适用于有多个域或多个端口请求同样内容的情况。如果有需要,我们可以对calculateKey方法进行重写,从而实现我们自己的计算key的逻辑。这个是很有必要的,因为在项目中很多页面都使用AJAX,为保证JS请求的数据不被浏览器缓存,每次请求可能都会是不同的数参数。如果使用 SimplePageCachingFilter,那么每次生成的key都不一样,缓存就没有意义了。这种情况下,我们就会覆写 calculateKey()方法。
2 .SimpleCachingHeadersPageCachingFilter 提供HTTP缓存头信息,这个不介绍了用的很少。
3 .SimplePageFragmentCachingFilter
SimplePageCachingFilter适用于缓存整个页面的情况,如果只需要缓存某一个片段,如使用jsp:include包含的部分,这个时候就需要用SimplePageFragmentCachingFilter。
第一部分是页面整体缓存
第一步:首先配置ehcache.xml指定我们的SimplePageCachingFilter缓存 ,这里指定页面缓存的生命周期是60秒,还有timeToIdleSeconds的时间爱你是120秒,这里要注意下不要设置太长时间
<!-- 页面全部缓存 -->
<cache name="SimplePageCachingFilter"
maxElementsInMemory="10"
maxElementsOnDisk="10"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="120"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LFU">
</cache>
第二步 : 在web.xml中添加页面缓存过滤器PageCachingFilter。
注意: 如果我们在ehcache.xml中命名的页面缓存名字为SimplePageCachingFilter时,我们再web.xml中的页面缓存过滤器的cacheName是可以不用定义的,因为它是默认的;如果不是SimplePageCachingFilter,这是我就必须指定cacheName了。
还有一点url-pattern的指定应该是/pageCacheController/testPageCache.do,而不是/testPageCache.do这个。
<!--ehcache 页面缓存过滤器 -->
<filter>
<filter-name>PageCachingFilter</filter-name>
<filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class>
<init-param>
<param-name>cacheName</param-name>
<param-value>SimplePageCachingFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PageCachingFilter</filter-name>
<url-pattern>/pageCacheController/testPageCache.do</url-pattern>
</filter-mapping>
第三步 : 编写controller测试类
@Controller
@RequestMapping("pageCacheController")
public class PageCacheController { private final static Logger log = Logger.getLogger(PageCacheController.class); @RequestMapping("testPageCache")
public ModelAndView testPageCache(){
ModelMap model = new ModelMap();
Date date = new Date();
model.addAttribute("date", date.toLocaleString() );
log.info("我来访问controller了");
return new ModelAndView("testPageCache",model);
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>测试</title>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery-1.11.1.min.js"></script> <script type="text/javascript"> </script>
</head> <body>
<h1>这是一个页面缓存的练习</h1>
<font style="color:green;font-weight:bold;font-size: 18px">${date}</font><br><br>
</body>
</html>
上面这个是testPageCache.jsp页面
第四步 : 访问/pageCacheController/testPageCache.do观察页面时间并查看控制台输出,在该缓存的生命周期内,即60秒之间刷新页面,页面上的时间是不会变化的,当过了缓存的生命周期在访问,时间立马改变。下面看看图。
在60秒内刷新页面观看控制台。发现“我来访问controller了”没有打印出来,也就是说在缓存生命周期内我们第二次访问时,只经过了page-filter-action-service-dao-db 中的page-filter其余的部分都没有访问。如果你亲自做过的话你会对控制台打印的信息会产生兴趣的,我这里给指出一个重要的Cache-control-> max-age=0,这个你们可以研究研究,我就不说了。
到这里页面整体缓存的简单例子就完成了,当然实际项目中肯定比这复杂,但是道理是一样的。只要你明白其中的原理,那么一切OK!
第二部分是页面局部缓存
道理跟上面的一样我就简单说了
配置ehcache.xml
<!-- 页面局部缓存 -->
<cache name="SimplePageFragmentCachingFilter"
maxElementsInMemory="10"
maxElementsOnDisk="10"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="120"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LFU">
</cache>
配置web.xml,这里需要注意几点,我们include的jsp页面在filter中要指定<dispatcher>INCLUDE</dispatcher>,如果没有指定任何< dispatcher >元素,默认值是REQUEST就不会拦截了。我这里有新增加了一个页面作为include的页面
<!--ehcache 页面局部缓存 -->
<filter>
<filter-name>PageFragmentCachingFilter</filter-name>
<filter-class>net.sf.ehcache.constructs.web.filter.SimplePageFragmentCachingFilter</filter-class>
<init-param>
<param-name>cacheName</param-name>
<param-value>SimplePageFragmentCachingFilter</param-value>
</init-param>
</filter>
<!-- This is a filter chain. They are executed in the order below.Do not change the order. -->
<filter-mapping>
<filter-name>PageFragmentCachingFilter</filter-name>
<url-pattern>/page/testPageFragmentCache.jsp</url-pattern>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
testPageFragmentCache.jsp页面,为了方便我还是调用了上边的controller方法来观察时间。如果你是按照我的做法一步一步做的话,要测试局部缓存时,需要把页面整体缓存的filter注释掉,实际中不需要,只是我为了偷懒用了相同访问地址
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>测试</title>
</head>
<body>
<h1>这是include的jsp页面</h1>
<font style="color:green;font-weight:bold;font-size: 18px">${date}</font><br><br>
</body>
</html>
下面来看效果图
刷新页面,没有变化说明我们include的页面被缓存了
来看看控制台变化
OK页面缓存简单的内容基本写完了,有不合理的地方请大家指正。
ehcache实现页面整体缓存和页面局部缓存的更多相关文章
- ehcache 页面整体缓存和局部缓存
页面缓存是否有必要?. 这样说吧,几乎所有的网站的首页都是访问率最高的,而首页上的数据来源又是非常广泛的,大多数来自不同的对象,而且有可能来自不同的db ,所以给首页做缓存是很必要的.那么主页的缓存策 ...
- 1.ehcache实现页面整体缓存和页面局部缓存
转自:https://www.cnblogs.com/jianjianyang/p/4933016.html 好长时间没写博客了,真的是没时间啊.ps:其实就是懒!!接下来几篇要写下缓存,这里主要写下 ...
- ASP.NET缓存全解析3:页面局部缓存 转自网络原文作者李天平
有时缓存整个页面是不现实的,因为页的某些部分可能在每次请求时都需要变化.在这些情况下,只能缓存页的一部分.顾名思义,页面部分缓存是将页面部分内容保存在内存中以便响应用户请求,而页面其他部分内容则为动态 ...
- asp.net MVC3的局部缓存页面PartialCache.cshtml
MVC3及以上有了PartialCache.cshtml局部缓存的方式,具体实现: 新建一个PartialCache.cshtml的页面,在控制器上写上如下代码: [OutputCache(Durat ...
- Ehcache(09)——缓存Web页面
http://haohaoxuexi.iteye.com/blog/2121782 页面缓存 目录 1 SimplePageCachingFilter 1.1 calculate ...
- 在Spring中使用cache(EhCache的对象缓存和页面缓存)
Spring框架从version3.1开始支持cache,并在version4.1版本中对cache功能进行了增强. spring cache 的关键原理就是 spring AOP,通过 spring ...
- 使用Varnish+ESI实现静态页面的局部缓存(思路篇)
使用Varnish+ESI实现静态页面的局部缓存(思路篇) 页面静态化是搭建高性能网站必用的招式之一,页面静态化可以有效提升系统响应速度,同时也有利于搜索引擎优化.但在页面静态化后,静态页面之间包含( ...
- OScached缓存整个页面和缓存局部页面
1.缓存整个页面 在OSCache组件中提供了一个CacheFilter用于实现页面级的缓存.主要用于对web应用中的某些动态页面进行缓存,尤其是那些需要生成PDF格式文件/报表.图片文件等的页面,不 ...
- angular页面缓存与页面刷新
angularJS学习笔记:页面缓存与页面刷新 遇到的问题 现在存在这样一个问题,登录前与登录成功后是同一个页面,只不过通过ngIf来控制哪部分显示,图像信息如下: 所以,整体工作不是很难,无非就 ...
随机推荐
- Intel S5000VSA(SAS)主板设置RAID 步骤【转】
Intel S5000VSA(SAS)主板设置RAID 步骤 我近日亲自安 装了一台服务器,用的是intel S5000VSA 4DIMM主板,因为在安装过程中没有注意到一些细节,所以在安装时碰到了一 ...
- JSON.parse()和JSON.stringfy()
JSON.parse()从字符串中解析出JSON对象: var data = '{"a":1,"b":2}'; JSON.parse(data); JSON.s ...
- Date Json格式转换Date格式
CreateTime=\/Date(1458722493663+0800)\/ var CreateTime="/Date(1458722493663+0800)/";var st ...
- hihocoder [Offer收割]编程练习赛14 剑刃风暴
题目4 : 剑刃风暴 时间限制:20000ms 单点时限:2000ms 内存限制:256MB 描述 主宰尤涅若拥有一招非常厉害的招式——剑刃风暴,“无论是战士还是法师,都害怕尤涅若的武士刀剑技”. 现 ...
- [Bootstrap] install Bootstrap framework in window 7 by npm
Install with npm You can also install Bootstrap using npm: $ npm install bootstrap require('bootstra ...
- CentOS7.4使用yum安装MySQL5.6
CentOS默认数据库为mariadb可以使用yum安装MySQL5.6 系统版本查看 下载yum源安装 wget http://dev.mysql.com/get/mysql-community-r ...
- debug kibana in chrome
kibana5.6.5版本 在kibana根目录运行命令:NODE_OPTIONS='--inspect --debug' npm start 也可以尝试命令:NODE_OPTIONS="- ...
- 怎么将Android的API demo导入到Eclipse工作区中
File ->New Android Project 选择Create project from existing sample (不同Android版本有对应的ApiDemo示例).
- 白话陈述之——从python脚本变化解析由路径引起的GP服务运行失败问题
补充一下未完待续的利用Python分析GP服务运行结果的输出路径 & 实现服务输出路径的本地化,这篇博客中主要介绍了如何实现将GP服务生成的结果输出至本地及输入输出路径导致GP服务运行失败的问 ...
- Redis 缓存穿透,缓存击穿,缓存雪崩的解决方案分析
设计一个缓存系统,不得不要考虑的问题就是:缓存穿透.缓存击穿与失效时的雪崩效应. 一.什么样的数据适合缓存? 分析一个数据是否适合缓存,我们要从访问频率.读写比例.数据一致性等要求去分析. 二.什么 ...