此文为摘录
浏览器缓存将文件保存在客户端,好的缓存策略可以减少对网络带宽的占用,可以提高访问速度,提高用户的体验,还可以减轻服务器的负担。因此我们有必要了解它的实现原理,用来提高网站的性能。
当一个客户端请求web服务器, 请求的内容可以从以下几个地方获取:服务器、浏览器缓存中或缓存服务器中。这取决于服务器端输出的页面信息。页面文件有三种缓存状态。
1.最新的:选择不缓存页面,每次请求时都从服务器获取最新的内容。
2.未过期的:在给定的时间内缓存,如果用户刷新或页面过期则去服务器请求,否则将读取本地的缓存,这样可以提高浏览速度。
3.过期的:也就是陈旧的页面,当请求这个页面时,必须进行重新获取。
页面的缓存状态是由http header决定的,一个浏览器请求信息,一个是服务器响应信息。主要包括Pragma: no-cache、Cache-Control、 Expires、 Last-Modified、If-Modified-Since。其中Pragma: no-cache由HTTP/1.0规定,Cache-Control由HTTP/1.1规定。
Cache-Control的主要参数
Cache-Control: private/public Public 响应会被缓存,并且在多用户间共享。 Private 响应只能够作为私有的缓存,不能再用户间共享。
Cache-Control: no-cache:不进行缓存
Cache-Control: max-age=x:缓存时间 以秒为单位
Cache-Control: must-revalidate:如果页面是过期的 则去服务器进行获取。
Expires:显示的设置页面过期时间
Last-Modified:请求对象最后一次的修改时间 用来判断缓存是否过期 通常由文件的时间信息产生
If-Modified-Since :客户端发送请求附带的信息 指浏览器缓存请求对象的最后修改日期 用来和服务器端的Last-Modified做比较
如IE的设置里面有四种方式(如图)的"每次访问页面检查",用户使用重新加载或超过了过期日期,浏览器就会认为这个页面是陈旧的(它将发送附加一个If - Modified-Since的信息. 如果页面没有改变,服务器端响应一个304状态 Not Modified,而不发送整个页面,这样就会很快,但服务器必须要生成有效的Last-Modified headers且服务器时间必须是有效的。
一个不进行缓存的服务器端响应
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 19662
Pragma: no-cache
Cache-Control: no-cache
Server: Roxen/2.1.185
Accept-Ranges: bytes
Expires: Wed, 03 Jan 2001 00:18:55 GMT
有时候仅仅设置Pragma: no-cache Cache-Control: no-cache 还是不保险,需要将过期时间设置成过去的时间就确保了对象不被缓存。
一个允许缓存的服务器端响应
HTTP/1.1 200 OK
Date: Tue, 13 Feb 2001 14:50:31 GMT
Server: Apache/1.3.12
Cache-Control: max-age=43200
Expires: Wed, 14 Feb 2001 02:50:31 GMT
Last-Modified: Sun, 03 Dec 2000 23:52:56 GMT
ETag: "1cbf3-dfd-3a2adcd8"
Accept-Ranges: bytes
Content-Length: 3581
Connection: close
Content-Type: text/html
Cache-Control: max-age=43200 表示缓存12个小时
我们来看一个浏览器缓存的具体例子
第一次请求文件
Request:
GET /file.html HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-comet, */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
Host: 24.5.203.101
Connection: Keep-Alive
Response:
HTTP/1.1 200 OK
Date: Tue, 13 Feb 2001 20:00:22 GMT
Server: Apache
Cache-Control: max-age=604800
Last-Modified: Wed, 29 Nov 2000 15:28:38 GMT
ETag: "1df-28f1-3a2520a6"
Accept-Ranges: bytes
Content-Length: 10481
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
这里返回了Last-Modified和ETag,这两个信息就是用来以后比较当前浏览器缓存的文件是否和服务器端文件一致,如果不一直就获取最新,一直则读取本地缓存。
第二次请求
Request:
GET /file.html HTTP/1.1
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
If-Modified-Since: Wed, 29 Nov 2000 15:28:38 GMT
If-None-Match: "1df-28f1-3a2520a6"
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
Host: 24.5.203.101
Connection: Keep-Alive
Response:
HTTP/1.1 304 Not Modified
Date: Tue, 13 Feb 2001 20:01:07 GMT
Server: Apache
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
ETag: "1df-28f1-3a2520a6"
Cache-Control: max-age=604800
请求中的If-None-Match信息就是第一次响应的ETag,用来验证和当前响应的ETag是否一致。服务器返回Not Modified,浏览器就读取本地缓存。
我们还可以使用专门缓存服务器来改善性能。他的原理和浏览器的缓存原理一样,所有的浏览器请求将由缓存服务器响应,缓存服务器可以用自己的缓存文件或获取新的文件来响应用户的请求。因此有了缓存服务器的,将大大提高网站的性能
基于上面的对浏览器的缓存机制的了解,下面针对java项目中关于缓存处理的一个例子罗列:
一、设计思路以及代码示例:
1、通过filter对http请求的某些属性值进行设置
因为所有的请求以及响应都必须要通过filter的,所以,我们可以通过filter进行设置。
而浏览器的资源是否会得到缓存,是通过响应的header来设置的。
a、先将需要设置的值,在web.xml中作为filter的初始化变量设置进去,等到web应用起来以后,必定会通过init()方法传递到filter中。
web.xml如下所示:
<filter>
<filter-name>NoCache</filter-name>
<filter-class>com.superkaiwii.core.web.filter.ResponseHeaderFilter</filter-class>
<init-param>
<param-name>Cache-Control</param-name>
<param-value>no-cache, must-revalidate</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>NoCache</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
利用filter对每个请求的header作处理。ResponseHeaderFilter的示例代码如下所示:
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class ResponseHeaderFilter
implements Filter
{
private FilterConfig fc;
public void doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain)
throws IOException, ServletException
{
HttpServletResponse localHttpServletResponse = (HttpServletResponse)paramServletResponse;
Enumeration localEnumeration = this.fc.getInitParameterNames();
while (localEnumeration.hasMoreElements())
{
//每一个通过这个filter的请求,filter都将<init-param>的参数值赋值到响应的header中
String str = (String)localEnumeration.nextElement();
localHttpServletResponse.addHeader(str, this.fc.getInitParameter(str));
}
paramFilterChain.doFilter(paramServletRequest, localHttpServletResponse);
}
/**
* 将web.xml中的<init-param> 值传递过来
*/
public void init(FilterConfig paramFilterConfig)
{
this.fc = paramFilterConfig;
}
public void destroy()
{
this.fc = null;
}
}
2、白名单与黑名单结合
因为大部分的资源是不需要缓存的,而少部分(诸如,ext,图片等)的资源需要在短时间内缓存的。
所以,我们可以将全部的请求设置为不缓存,然后将需要缓存的部分再附加设置值。
可以,参考我的web.xml:
<!-- 不进行缓存 -->
<filter>
<filter-name>NoCache</filter-name>
<filter-class>com.superkaiwii.core.web.filter.ResponseHeaderFilter</filter-class>
<init-param>
<param-name>Cache-Control</param-name>
<param-value>no-cache, must-revalidate</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>NoCache</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<!-- 进行缓存 ,开发时可去掉该缓存配置-->
<!--max-age=604800,以秒为单位,这个值即为:一周 -->
<filter>
<filter-name>CacheForWeek</filter-name>
<filter-class>com.superkaiwii.core.web.filter.ResponseHeaderFilter</filter-class>
<init-param>
<param-name>Cache-Control</param-name>
<param-value>max-age=604800, public</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheForWeek</filter-name>
<url-pattern>/images/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CacheForWeek</filter-name>
<url-pattern>/ext3/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CacheForWeek</filter-name>
<url-pattern>/js/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CacheForWeek</filter-name>
<url-pattern>/css/*</url-pattern>
</filter-mapping>
相关推荐
服务器缓存是提升网站或应用性能的关键技术,它通过存储常用数据或计算结果,减少对主服务器或外部资源的访问,从而显著加快响应速度。在本文中,我们将深入探讨服务器缓存的工作原理、常见类型、设置方法以及如何...
这是因为Java插件倾向于从缓存中获取Applet的jar文件,而非直接从服务器获取最新版本。 清除Java Applet缓存的方法有多种。首先,你可以尝试通过Java控制台来删除缓存。在Java控制台中,你可以找到“清除类载入程序...
JAVA的缓存应用主要涉及到Java内存体系的理解、基础缓存的使用、缓存框架的介绍以及内存溢出状况的分析和内存检查工具的使用。在深入探讨这些话题之前,我们首先需要了解Java内存体系的基本概念。 Java内存体系主要...
Java缓存技术是提高应用程序性能的关键工具,尤其是在处理大量数据时。它通过存储频繁访问的数据在内存中,避免了重复的数据库查询,显著提升了响应速度。在这个“Java缓存技术的使用实例”中,我们将深入探讨Java...
在构建大型网站时,Web服务器缓存是一种至关重要的优化策略,它可以显著提高系统性能和响应速度,降低服务器负载。本文将深入探讨四种主要的缓存技术:CDN缓存、反向代理缓存、应用程序缓存和分布式缓存,以及讨论...
4. Web服务器缓存:如Apache的 mod_cache,减轻应用服务器压力。 5. 客户端浏览器缓存:存储静态资源,减少对网站的请求。 数据库缓存是关键部分,尤其是对于处理大量数据和频繁查询的企业级应用。MySQL的Query ...
在Java服务器高级编程领域,开发者通常需要掌握一系列深入的技术和概念,以构建高效、可扩展且可靠的网络应用程序。本文将围绕Java服务器编程的关键知识点展开,包括但不限于Servlet、JSP、EJB、Spring框架、微服务...
本文将深入探讨“java缓存代码,tomcat JVM配置”这一主题,包括Java缓存的实现方法以及如何对Tomcat服务器进行JVM配置和连接池设定,以提升系统效率。 首先,我们来看Java缓存代码。在Java中,缓存是一种常见的...
- Redis客户端Jedis、Lettuce:用于Java程序与Redis服务器交互,实现分布式缓存功能。 总结,Java缓存技术是提升系统性能的重要手段,理解其原理和使用方式,结合合适的缓存库,可以有效地优化应用程序的性能,...
- **Cache 定义**:Cache 通常被用来协调不同速度设备之间的数据传输,包括硬件级别的 CPU Cache 和软件层面的浏览器缓存、服务器缓存等。Memcached 属于广义上的 Cache,它是一个基于内存的分布式缓存系统。 - **...
在实践中,合理配置缓存大小、设置合适的过期策略、处理缓存一致性问题(如缓存穿透、缓存雪崩和缓存击穿)等都是挑战。开发者需要根据业务场景进行权衡,以确保缓存能带来性能提升而不是引入新的问题。 总结来说,...
"一个基于Ajax和Java缓存的聊天室"这个标题揭示了该项目的核心技术栈,即使用Ajax进行实时通信,以及Java作为后端处理数据并实现缓存功能,构建了一个在线聊天平台。Ajax(Asynchronous JavaScript and XML)是一种...
OSCache和Ehcache应用介绍,主要对页面缓存、服务器缓存相关应用的介绍
- **特点**:Ehcache不仅支持内存缓存,还支持磁盘缓存,这意味着即使在服务器重启之后,缓存中的数据仍然可以保留下来。此外,Ehcache还提供了多种缓存策略,如最近最少使用(LRU)算法,以及多种缓存加载器和缓存...
分布式缓存使得缓存数据可以跨应用服务器和网络进行共享。memcached是一个高性能的分布式缓存系统,通常用作数据库查询结果的缓存,减少数据库的负载。 文档提到了多种缓存框架和API,比如Ehcache、JCS(Java ...
本主题将深入探讨如何使用Java语言来编写这样的代理服务器。以下是对这个主题的详细解析: 首先,理解HTTP代理服务器的基本原理是必要的。HTTP代理服务器作为客户端与目标服务器之间的中介,它接收客户端的HTTP请求...
**Java缓存框架 EhCache** EhCache是一个广泛使用的开源Java缓存框架,它以其高效、轻量级和易于集成的特性,在Java开发领域中占据了重要的地位。作为进程内缓存解决方案,EhCache能够在应用程序运行时存储数据,...
6. 监听事件:某些客户端库支持监听缓存操作事件,以便在数据变化时做出相应处理。 **示例代码** ```java import net.spy.memcached.*; public class MemcachedExample { public static void main(String[] ...
### Java版Memcache缓存管理与开发 #### Memcache简介及其在高流量网站中的作用 在高流量网站中,为了缓解数据库的压力并提高网站响应速度,通常会采用Memcache作为缓存解决方案。Memcache是一种高性能、分布式...