使用ehcache缓存页面、ExpiresFilter添加Expires头,大幅提升网站性能

本文主要是介绍使用ehcache缓存页面、ExpiresFilter添加Expires头,大幅提升网站性能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前几天把网站部署到服务器上后发现访问速度和龟速差不多,内心感到非常焦虑——之前并未做过这方面的尝试,要解决问题实在有些头大。

但幸好之前做过一个项目,本地访问速度感觉奇慢,但正式环境下访问速度反倒快得飞起。虽然我期初并不知晓原因,但这毕竟是解决问题的线索。

追本溯源的找,情况倒也不难办。

  1. ehcache
  2. org.apache.catalina.filters.ExpiresFilter

ehcache是我找到的一个关键信息。虽然之前我们素未谋面,但cache的中文意思是缓存,这一点英语能力我还是有的。另外,我之前写过一篇文章《为组件添加Expires头,最大化利用浏览器缓存》,虽然文章现在看来很糟糕,但至少提供了信息给我——org.apache.catalina.filters.ExpiresFilter。

利用这两点,至少暂时解决了问题,尽管ehcache我很不熟,就算是看了很多文档和博客,依然懵懵懂懂。但本着解决问题的原则,我发现我至少会用它们俩。

首先来说ehcache。

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。

经过大量的调查和尝试后,找到了——SimplePageCachingFilter:

它是ehcache-web模块下页面缓存Filter的一个简单实现,适用于可以压缩的Http响应(response),如HTML、XML、JSON等。

页面缓存主要用Filter过滤器对请求的url进行过滤,如果该url在缓存中出现。那么页面数据就从缓存对象中获取,并以gzip压缩后返回。其速度是没有压缩缓存时速度的3-5倍,效率相当之高!其中页面缓存的过滤器有CachingFilter,一般要扩展filter或是自定义Filter都继承该CachingFilter。

第一步,在pom.xml文件中添加ehcache的依赖:

<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core -->
<dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache-core</artifactId><version>2.6.11</version>
</dependency><!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-web -->
<dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache-web</artifactId><version>2.0.4</version>
</dependency>

第二步,在classpath下新建ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache><cache name="SimplePageCachingFilter" maxEntriesLocalHeap="1000" eternal="false"overflowToDisk="true" timeToIdleSeconds="120" timeToLiveSeconds="120" memoryStoreEvictionPolicy="LFU" /></ehcache>
  1. 名字必须为SimplePageCachingFilter;
  2. maxEntriesLocalHeap=”1000” : 堆内存中最大缓存对象数,0没有限制(必须设置);
  3. eternal=”false” : 对象是否永久有效,一但设置了,timeout将不起作用。 (必须设置)
  4. overflowToDisk=”false” : 当缓存达到maxElementsInMemory值时,是否允许溢出到磁盘(必须设置)(内存不足时,是否启用磁盘缓存。)
  5. timeToIdleSeconds=”120” : 导致元素过期的访问间隔(秒为单位),即当缓存闲置n秒后销毁。 当eternal为false时,这个属性才有效,0表示可以永远空闲,默认为0
  6. timeToLiveSeconds=”120” : 元素在缓存里存在的时间(秒为单位),即当缓存存活n秒后销毁. 0 表示永远存在不过期
  7. memoryStoreEvictionPolicy=”LFU” : 当达到maxElementsInMemory时,如何强制进行驱逐,默认使用”最近使用(LRU)”策略,其它还有先入先出FIFO,最少使用LFU,较少使用LRU

第三步,在web.xml中配置ehcache 页面缓存过滤器:

<!--ehcache 页面缓存过滤器 -->
<filter><filter-name>PageCachingFilter</filter-name><filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class>
</filter>
<filter-mapping><filter-name>PageCachingFilter</filter-name><url-pattern>/mec/good</url-pattern>
</filter-mapping>

这里我只添加了访问比较频繁的首页路径。

完成之后,启动tomcat,发现如下日志:

DEBUG 2018-05-08 10:37:02,920 net.sf.ehcache.constructs.web.filter.Filter: Request Headers: host -> localhost:8880: connection -> keep-alive: cache-control -> max-age=0: upgrade-insecure-requests -> 1: user-agent -> Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36: accept -> text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8: referer -> http://localhost:8880/zmeng/initLogin?backToUrl=http%3A%2F%2Flocalhost%3A8880%2Fzmeng%2Fmec%2Fgood: accept-encoding -> gzip, deflate, br: accept-language -> zh-CN,zh;q=0.9: cookie -> JSESSIONID=6BFDADE7284DF880D35D4866632C3FAE; Hm_lvt_82116c626a8d504a5c0675073362ef6f=1521712436,1524018865,1524206145; COOKIE_MEMBER_HEADIMAGE="http://wx.qlogo.cn/mmopen/oiazmgRzbajknOWTxtDgxibicdQcnhicNbNRiap0gOTyPWWDKwibTtlaUHDm22ibWiaAJ7ibVsjjFQibZ6j3Mcwic2g5qicUyMsC2YVFjhFM/0"; COOKIE_MEMBER=3l+5WJRuO2mF/7lj0JsJ0FSTYJEg5xaV
DEBUG 2018-05-08 10:37:02,920 net.sf.ehcache.constructs.web.filter.CachingFilter: Thread http-bio-8880-exec-13  has been marked as visited.
DEBUG 2018-05-08 10:37:02,921 net.sf.ehcache.constructs.web.filter.Filter: Request Headers: host -> localhost:8880: connection -> keep-alive: cache-control -> max-age=0: upgrade-insecure-requests -> 1: user-agent -> Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36: accept -> text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8: referer -> http://localhost:8880/zmeng/initLogin?backToUrl=http%3A%2F%2Flocalhost%3A8880%2Fzmeng%2Fmec%2Fgood: accept-encoding -> gzip, deflate, br: accept-language -> zh-CN,zh;q=0.9: cookie -> JSESSIONID=6BFDADE7284DF880D35D4866632C3FAE; Hm_lvt_82116c626a8d504a5c0675073362ef6f=1521712436,1524018865,1524206145; COOKIE_MEMBER_HEADIMAGE="http://wx.qlogo.cn/mmopen/oiazmgRzbajknOWTxtDgxibicdQcnhicNbNRiap0gOTyPWWDKwibTtlaUHDm22ibWiaAJ7ibVsjjFQibZ6j3Mcwic2g5qicUyMsC2YVFjhFM/0"; COOKIE_MEMBER=3l+5WJRuO2mF/7lj0JsJ0FSTYJEg5xaV
DEBUG 2018-05-08 10:37:02,921 net.sf.ehcache.constructs.web.filter.Filter: Request Headers: host -> localhost:8880: connection -> keep-alive: cache-control -> max-age=0: upgrade-insecure-requests -> 1: user-agent -> Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36: accept -> text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8: referer -> http://localhost:8880/zmeng/initLogin?backToUrl=http%3A%2F%2Flocalhost%3A8880%2Fzmeng%2Fmec%2Fgood: accept-encoding -> gzip, deflate, br: accept-language -> zh-CN,zh;q=0.9: cookie -> JSESSIONID=6BFDADE7284DF880D35D4866632C3FAE; Hm_lvt_82116c626a8d504a5c0675073362ef6f=1521712436,1524018865,1524206145; COOKIE_MEMBER_HEADIMAGE="http://wx.qlogo.cn/mmopen/oiazmgRzbajknOWTxtDgxibicdQcnhicNbNRiap0gOTyPWWDKwibTtlaUHDm22ibWiaAJ7ibVsjjFQibZ6j3Mcwic2g5qicUyMsC2YVFjhFM/0"; COOKIE_MEMBER=3l+5WJRuO2mF/7lj0JsJ0FSTYJEg5xaV

并且在120s之内页面上的时间并未发生改变:

这里写图片描述

120s之后再去访问的时候就发现时间已经发生了变化,并且页面被重新缓存。

尽管对ehcache非常皮毛,但总算是hello world了一次。以后我会再做新的研究并且把心得整理出来。

再来说ExpiresFilter。

 ExpiresFilter是Java servlet API 当中的一部分,它负责控制设置response当中的响应头(Expires) 和 ( Cache-Control的max-age),过期时间可以设置为相对于源文件的最后修改时间,或者浏览器的访问时间。

  这些响应头指示浏览器控制文档的缓存,如果使用了缓存,那么浏览器在下一次获取文档(HTML)的时候就会从本地缓存中获取,而不是访问实际的资源服务器,除非超过失效时间。关于HTTP头控制客户端缓存的更多介绍请参见我的另外一篇文章,http://www.cnblogs.com/daxin/p/3981553.html或者可以直接查阅HTTP协议(see RFC 2616 section 14.9)。

使用ExpiresFilter就简单得多了,虽然SimplePageCachingFilter也不麻烦。

在web.xml文件中添加ExpiresFilter,内容如下:

<filter><filter-name>ExpiresFilter</filter-name><filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class><init-param><param-name>ExpiresByType image</param-name><param-value>access plus 10 days</param-value></init-param><init-param><param-name>ExpiresByType text/css</param-name><param-value>access plus 10 days</param-value></init-param><init-param><param-name>ExpiresByType application/javascript</param-name><param-value>access plus 10 days</param-value></init-param>
</filter>
<filter-mapping><filter-name>ExpiresFilter</filter-name><url-pattern>/*</url-pattern><dispatcher>REQUEST</dispatcher>
</filter-mapping>

其作用就是对image、css、JavaScript添加Expires头。

这里写图片描述

完成之后就可以看到css文件已经被缓存起来了。

这篇关于使用ehcache缓存页面、ExpiresFilter添加Expires头,大幅提升网站性能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/624102

相关文章

使用Python开发一个Ditto剪贴板数据导出工具

《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.