HTTP之缓存技术
1. 缓存简介
缓存是位于服务器和客户端的中间单元,主要根据用户代理发送过来的请求,向服务器请求相关内容后提供给用户,并保存内容副本,例如 HTML 页面、图片、文本文件或者流媒体文件。然后,当下一个针对相同 URL 的请求到来时,缓存直接使用副本来响应 HTTP 请求,而不需要向源服务器再次发送请求。
1.1 缓存的好处
- 减少响应延迟。缓存服务器距离用户更近,如果可以直接提供服务,响应时延将大大减少,使用户感觉 Web 服务器反应更块。
- 减少网络带宽消耗。当缓存直接使用副本为用户服务时,缓存与源服务器之间的通信链路带宽消耗将大大降低,提供服务的缓存越靠近用户,节约的网络资源越多,特别是对于拥塞程度较高的运营商骨干网来说更说如此。
- 降低源服务器负载。用户原本需要访问源服务器的大量请求都在缓存内直接得到服务,源服务器的响应次数大量降低。
2. 缓存的基本工作原则
- 如果响应消息的头信息告诉缓存不要保留副本,缓存就不会缓存相应内容。
- 如果请求信息需要源服务器认证或者涉及安全协议,相应的请求内容也不会被缓存。
- 如果缓存的内容含有以下信息,内容将会被认为是足够新的,因此不需要从源服务器重新获取内容。
- 含有过期时间和寿命信息,并且此时内容仍然没有过期。
- 缓存内容近期被用来提供过服务,并且内容的最后更新时间相对于最近使用的时间较久。
- 如果缓存的内容已经过期,缓存服务器将向源服务器发出验证请求(通过 ETag 头信息或者 Last-Modified 头信息),用于确定是否可以继续使用当前内容直接提供服务。
- 在某些情况下(比如源服务器从网络断开了),缓存的内容在过期的情况下也可以直接提供服务。
- 如果在响应消息中不存在用于判断内容是否变化的验证值(ETag 头信息或者 Last-Modified 头信息),并且也没有其他任何明显的新鲜度信息,内容通常不会被缓存。
3. 控制 HTTP 缓存的方法
1. HTML META 标签和 HTTP 头信息
HTML 文件的编写者会在文档的<HEAD>
区域中加入描述文档的各种属性,这些 META 标签常常被用于标记文档不可以被缓存或者标记多长时间后过期。META 标签使用很简单,但是效率不高,因为能够读懂这个标记的浏览器只有少许几种,同时由于中间缓存几乎完全不解析文档中的 HTML 内容,所以也没有什么中间缓存(代理缓存和网关缓存)能读懂这个规则。如果要通过 META 标签来控制页面不缓存,一般情况下会在 Web 页面的<HEAD>
区域中增加 "Pragma: no-cache" 的 META 标记。
2. 使用 Expires(过期时间)头信息来控制保鲜期
通常情况下,主要通过 HTTP 头信息来指示缓存和控制内容是否缓存。这些控制信息在 HTML 代码中是看不见的,一般由 Web 服务器自动生成,并在 HTTP 消息中进行标识。一个典型的 HTTP 1.1 协议响应消息的头信息看上去如下:
HTTP/1.1 200 OK
Data: Mon, 18 Jul 2011 22:14:49 GMT
Server: Apache
Cache-Control: max-age=3600, must-revalidate
Expires: Mon, 18 Jul 2011 23:14:49 GMT
Last-Modified: Sun, 5 Jun 2011 16:38:21 GMT
ETag: "5e36-767-576df70c"
Content-Length: 1040
(空行)
HTML 代码
该代码中包含了 Expires 头,指示Mon, 18 Jul 2011 23:14:49 GMT
为过期时间。Expires 方式是 HTTP 控制缓存的基本手段,这个属性告诉缓存相关内容在多长时间内是新鲜的。过了这个时间,如果客户端向缓存请求这个内容,缓存就会向源服务器发送请求,检查文档是否已经发生了变化。大部分 Web 服务器设置 Expires 方式有多种,最常用的是设置成一个绝对的时间值,比如将内容最后被修改的时间点加上一个特定的时间段(比如一个小时)所得到的时间值。
3. 验证
在 HTTP 1.1 中对缓存提出了验证的概念,验证的目的就是检验缓存内容是否可用。当中间缓存存在一个过期的缓存内容,并且对应的访问请求到达时,缓存应该首先向源服务器或者其他保存有未过期的缓存服务器请求验证来确定本地的缓存内容是否可用。这个过程就是一个缓存消息的验证过程。
HTTP 1.1 把这种验证后再决定是否返回消息内容的方式叫 "有条件" 的请求返回方法,这样可以避免从源服务器或其他缓存服务器获取整个内容的消息,从而减少网络流量。当源服务器生成了一个完整的响应消息时,它会附带一个验证消息,中间缓存在缓存内容时可以保存这个验证信息,当缓存内容过期以后,中间缓存可以使用它生成一个 "有条件" 的请求来向源服务器请求验证。而源服务器或者在源服务器通信的路径上的其他缓存服务器(如果保存有未过期的内容)在收到这样的请求以后就可以将请求中包含的验证信息与自己本地的验证信息进行比较。如果两个验证信息相等,那么返回一个带有特定状态码(如 304 Not Modified,表示内容未修改过)且消息主体内容为空的响应消息,在这种情况下就减少了网络流量;如果两个验证信息不相等就需要传输一个包含新内容的完整响应消息。
4. Cache-Control(缓存控制)HTTP 头信息
指定过期时间和验证是 HTTP 1.1 的基本缓存机制,也是缓存的隐含指令。但是在某些情况下,服务器或客户端可能需要给 HTTP 缓存提出显示的指令。因此,HTTP 1.1 使用 Cache-Control 响应头信息来让网站的发布者可以更安全的控制他们的内容,并对过期时间进行限制。
有用的 Cache-Control 响应头信息包括如下几项:
- max-age:缓存内容保持新鲜状态的最长时间。这个属性类似于过期时间,是基于请求时间的相对时间间隔,而不是绝对过期时间,单位是秒,即从请求时间开始到过期时间之间的秒数。
- s-maxage:类似于 max-age 属性,它应用于共享缓存。
- public:此属性标记认证内容也可以被缓存,一般来说,经过 HTTP 认证才能访问的内容是默认不能缓存的。
- no-cache:强制将每次访问请求直接发送给源服务器,而不经过中间缓存进行前面提到的验证。这对那些需要在源服务器进行用户认证的应用非常有用,也适用于那些严格要求使用最新数据的应用。
- no-store:强制缓存在任何情况下都不要缓存任何内容。
- must-revalidate:告诉缓存必须遵循源服务器赋予的内容新鲜度。由于 HTTP 允许缓存在某些特定情况下返回过期数据,所以通过指定这个属性,源服务器可以告诉缓存,如果缓存内容处于过期状态,则在对访问请求进行响应前必须到源服务器进行重新验证。
- proxy-revalidate:proxy-revalidate 和 must-revalidate 基本相同,只是它不能应用于非共享的代理缓存。它允许在客户端缓存中保存那些经过权限认证的响应消息(包含有 "public" 来保证它们可以被缓存),在缓存内容没有过期之前,遇到相同的访问请求则可以返回缓存的数据而无须经过源服务器的验证,如果内容过期则仍需经过服务器重新验证。对于服务多个用户的代理缓存来说,为了保证每个用户都是被授权的,仍需每次都去服务器进行验证(这样的授权响应同样需要使用 public 指令来允许它们能够被缓存)。
5. Pragma HTTP 头信息
HTTP 还有一种缓存控制机制,为使用 Pragma HTTP 头信息的方式。Pragma 属于通用头,用来包含特定的执行指令,这些指令可以适用于客户端、代理、网关、源服务器中的任何接收者,但是 HTTP 协议中认为 Pragma 指令规定的行为是可选的。
当 "Pragma: no-cache" 出现在请求消息中时,即使缓存设备中缓存了此请求响应所需的内容,也会直接将此请求转发到源服务器上。虽然在 HTTP 1.1 中提到了通过 Pragma 控制缓存的方法,但这主要是为了向 HTTP 1.0 兼容,因为支持 HTTP 1.0 的缓存主要还是通过这种方法来控制内容缓存的。HTTP 1.1 中主要还是通过 Cache-Control 头信息来控制缓存,所以协议要求当一个 HTTP 1.1 的请求从客户端发出时,既应该包含 Pragma 指令,也应该包含 Cache-Control 的控制指令,这样,请求从客户端发给源服务器的过程中,分别支持 HTTP 1.1 和 HTTP 1.0 的缓存设备都可以读懂指令的信息。如果发送指令的客户端本身只支持 HTTP 1.0,那么支持 HTTP 1.1 的中间缓存在收到请求消息后必须以 Pragma 中的指令来控制缓存。
注:在 HTTP 规范中 Pragme 属性没有任何关于响应信息头 Pragma 属性的说明,它仅出现在请求头信息中,即头信息由浏览器发送给服务器,但实际上只有少数几种缓存服务器会遵循请求消息中的这个头信息。因此,在很多情况下,使用 Pragma 属性不一定管用。
HTTP之缓存技术的更多相关文章
- 网站缓存技术总结( ehcache、memcache、redis对比)
网站技术高速发展的今天,缓存技术已经成为大型网站的一个关键技术,缓存设计好坏直接关系的一个网站访问的速度,以及购置服务器的数量,甚至影响到用户的体验. 网站缓存按照存放的地点不同,可以分为客户端缓存. ...
- ASP.NET Core 缓存技术 及 Nginx 缓存配置
前言 在Asp.Net Core Nginx部署一文中,主要是讲述的如何利用Nginx来实现应用程序的部署,使用Nginx来部署主要有两大好处,第一是利用Nginx的负载均衡功能,第二是使用Nginx ...
- .Net环境下的缓存技术介绍 (转)
.Net环境下的缓存技术介绍 (转) 摘要:介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制的简单介绍和适用范围说明,以及设计缓存方案应该考虑的问题(共17页) 1 概念 ...
- [.net 面向对象程序设计进阶] (14) 缓存(Cache) (一) 认识缓存技术
[.net 面向对象程序设计进阶] (14) 缓存(Cache)(一) 认识缓存技术 本节导读: 缓存(Cache)是一种用空间换时间的技术,在.NET程序设计中合理利用,可以极大的提高程序的运行效率 ...
- 分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)
上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 安全性设置 设置客户端操作秘密 redis安装 ...
- 分布式缓存技术redis学习系列(一)——redis简介以及linux上的安装
redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssd ...
- PHP开发中的缓存技术汇总
在PHP开发中,出于对网站服务器负载的考虑,往往需要对页面.数据等内容进行缓存处理,下面就来看看,在PHP开发中有哪些缓存方式吧. 1.页面部分缓存该种方式,是将一个页面中不经常变的部分进行静态缓存, ...
- .Net环境下的缓存技术介绍
.Net环境下的缓存技术介绍 摘要: 介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制的简单介绍和适用范围说明,以及设计缓存方案应该考虑的问题(共17页) 1 概念 1.1 ...
- ASP.NET 缓存技术分析
缓存功能是大型网站设计一个很重要的部分.由数据库驱动的Web应用程序,如果需要改善其性能,最好的方法是使用缓存功能.可能的情况下尽量使用缓存,从内存中返回数据的速度始终比去数据库查的速度快,因而可以大 ...
- Android硬盘缓存技术DiskLruCache技术笔记
防止多图OOM的核心解决思路就是使用LruCache技术,但LruCache只是管理了内存中图片的存储与释放,如果图片从内存中被移除的话,那么又需要从网络上重新加载一次,这显然非常耗时.因此Googl ...
随机推荐
- caffe笔记
1. 训练 cifar10 示例 ① cd caffe.1.0.0 ./data/cifar10/get_cifar10.sh #获取图片 ② ./examples/cifar10/cre ...
- Socket的神秘面纱
Tcp/IP协议是目前世界上使用最为广泛的协议,是以Tcp/IP为基础多个层次上的协议的集合.也称Tcp/IP协议族或Tcp/IP协议栈. TCP: Transmission Control Prot ...
- IEnumerable<T>和IQuryable<T>的区别
https://stackoverflow.com/questions/1578778/using-iqueryable-with-linq/1578809#1578809 The main diff ...
- 运行tomcat7w.exe提示指定的服务未安装 解决办法
一.问题重现点击bin下tomcat7w.exe出现如下提示:提示指定的服务未安装 二.原因分析tomcat7.exe和tomcat7w.exe要起作用必须先为这两个文件安装服务.其中tomcat7. ...
- Django—ModelForm
简介 Model + Form ==> ModelForm.model和form的结合体,所以有以下功能: 验证 数据库操作 Form回顾 models.py class UserType(mo ...
- “System.Reflection.TargetInvocationException”类型的未经处理的异常在 mscorlib.dll 中发生
异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#signalR 第一种,权限不够,在项目运行的时候弹出==>解决方法:以管理员权限运行vs ...
- 团队第三次作业:Alpha版本发布
这个作业属于哪个课程 课程链接 这个作业要求在哪里 作业要求链接 团队名称 众志陈成 这个作业的目标 通过团队协作了解软件开发的大致流程,并在这个过程中体会调整与优化程序的方法,为以后真实的软件开发奠 ...
- 关于join() 是否会释放锁的一些思考
# 首先从一个很有意思的问题开始: - 问 : Thread 的join() 方法是否会释放锁? - 答: 会! # 如果一切到这里就结束了,那可能也就没有这篇小记了,但是我的脑子却冒出了一些奇怪的想 ...
- 使用pipenv管理你的python项目
怎么使用pipenv管理你的python项目 原文链接:https://robots.thoughtbot.com/how-to-manage-your-python-projects-with- ...
- Python3+Appium学习笔记03-启动app
这个是appium相关的官方api地址:http://appium.io/docs/en/about-appium/api/ 如同selenium进行自动化测试时,需要先创建一个浏览器实例一样.在使用 ...