美文网首页
使用 HTTP 缓存机制提升系统性能

使用 HTTP 缓存机制提升系统性能

作者: 杨啸 | 来源:发表于2023-08-27 10:37 被阅读0次

摘要

HTTP缓存机制定义在HTTP协议标准中,被现代浏览器广泛支持,同时也是一个用于提升基于Web的系统性能的广泛使用的工具。本文讨论如何使用HTTP缓存机制提升基于Web的系统,以及如何避免误用。同时也讨论了几种常见的应用场景。

一般性的缓存机制

抛开具体的技术实现,一般性来说在服务器-客户端模式下,缓存机制通常都是这么工作的,如图所示:

迁移过来,图丢了,文章太老了,懒得补了~~

当客户端需要获取某个资源的时候,首先查看客户端本地缓存中是否存在此资源。如果缓存中不存在这个资源,则必须要从服务器端把资源拉到本地。如果存在,则还需要判断缓存的资源是否过期。如果没过期,则从缓存中直接获取资源,不需要再从服务器端获取。如果过期了,则必须从服务器端获取最新资源。还有一种很可能出现的情况是客户端不知道服务器端的资源更新了没有,即不知道缓存中的资源是否过期。这种情况下,客户端还是要向服务器端发请求的,不过在请求中附加了一些信息。这些信息用于服务器判断客户端缓存中的资源是否过期,例如最后修改日期。服务器端如果发现缓存的资源并未过期,那么只需要返回一个信号,告诉客户端从缓存获取即可,并不需要返回资源的内容。

HTTP协议定义的缓存机制

当Web浏览器向服务器请求资源时(如下图所示),服务器可以在响应中包含缓存相关的HTTP头(HTTP Header)。这些HTTP Header会告诉浏览器是否以及如何缓存资源。

迁移过来,图丢了,文章太老了,懒得补了~~

关于缓存的HTTP Headers

下面列出的是关于缓存的HTTP Headers,它们有些是出现在响应(Response)中,有些在请求(Request)中。

HTTP Header 出现在
Cache-Control 响应
Expires 响应
Last-Modified 响应
If-Modified-Since 请求
ETag 响应
If-None-Match 请求

下面会一一介绍这些Header的用法,有一些是要配套使用的。

Cache-Control

在Chrome调试器中,可以在Response中找到Cache-Control,例如下图中的服务响应就包含一个Cache-Control头,其值为"public, max-age=30"

迁移过来,图丢了,文章太老了,懒得补了~~

Cache-Control的值一般为 [public | private | no-cache, no-store ], [max-age=n] ([A | B] 表示可以从A和B中取一个),"max-age=n"表示n秒后资源失效。

public是指资源应该被缓存,并且中间经过的代理服务器(假如有的话)也应该缓存这个资源。隐含的意思是,其他用户可能也能分享这个资源的缓存。
private是指资源应该被缓存,但是只能被客户端的浏览器缓存。
no-cache, no-store是指示资源不应该被缓存。
max-age是指缓存多长时间,单位是秒。

下面举几个常用的例子:

  1. Cache-Control : public, max-age=60

    告诉浏览器,当前资源应该被缓存,同时也告诉代理服务器(假如有的话)也可以缓存这个资源。缓存应该在60秒后过期。

  2. Cache-Control : private, max-age=60

    告诉浏览器,当前资源应该被缓存,同时也告诉代理服务器(假如有的话)不要缓存这个资源。缓存应该在60秒后过期。

  3. Cache-Control : no-cache, no-store
    告诉浏览器以及代理服务器,不要缓存这个资源。

Expires

是相对于max-age的另一种指示过期时间的方式。max-age表示多少时间后过期,而Expires表示在某个日期时间点后过期。换种通俗的说法,max-age相当于说“保质期六个月”,而Expires是说“在此日期之前”饮用。

注意:如果max-age和Expires同时存在,应该以max-age为准。但是通常可以把两个都设置成一个时间点。例如下面的JavaScript代码所示:

// 设置一年
res.setHeader('Cache-Control', 'public, max-age=31536000');
// Set expire date to 1 year later.
var currentDate = new Date((new Date()).getTime() + 3600 * 1000 * 24 * 365);
res.setHeader('Expires', currentDate.toUTCString());

限制:max-age和Expires设置的缓存过期时间最多为一年(365天),如果多于这个值则浏览器有可能会忽略。

Last-Modified 和 If-Modified-Since

Last-Modified出现在响应中,告诉浏览器当前资源的最后修改时间,例如:

Last-Modified: Mon, 03 Jan 2011 17:45:57 GMT

而If-Modified-Since出现在下次请求中,询问服务器当前缓存的资源是否已经过期,例如:

 If-Modified-Since: Mon, 03 Jan 2011 17:45:57 GMT

如果资源没有过期,则服务器应该返回304,不需要返回资源的内容。如果已过期,则服务器应该返回资源的内容到浏览器,并且返回200 HTTP状态码。

Last-Modified和If-Modified-Since配套使用,可以在保证不会误用缓存里的过期资源的前提下,减少服务器向浏览器发送的数据量,以及由于服务器在缓存未过期的情况下只需要返回304 HTTP状态码,而不需要返回整个资源的内容,也给了服务器优化的机会。

ETag 和 If-None-Match

Last-Modified 和 If-Modified-Since是用日期时间判断一个缓存的资源是否有效。ETag和If-None-Match则是用内容摘要作为判定的依据。内容摘要是指为一个资源的内容产生一串比较短的数字,当内容变化时,产生的数字串也会改变。内容摘要的算法有很多种,较常见的是SHA-1哈希算法、CRC32等。

ETag包含在服务器的响应中,为内容摘要。在下一次请求中,If-None-Match的值为上次的ETag的值。服务器根据If-None-Match的值(即内容摘要)判断缓存的资源是否有效。

304状态码

304状态码("Not Modified")表示资源(相对于缓存过的)没有被修改过。

检查请求与响应以及缓存工作情况

这里仅以Google Chrome为例,介绍如何检查请求与响应,以及检查浏览器缓存是否在发挥作用。其他的浏览器平台也是类似的。

打开Google Chrome,按F12,出现调试界面,切换到Network页。

迁移过来,图丢了,文章太老了,懒得补了~~

你会看到很多请求,包括URL、方法、状态等等,注意到上图有一栏显示的是"(from cache)",已经用红框标出。这表示这些资源都是从缓存里获取的,没有经过服务器。清除Cache之后,看到的会是浏览器从服务器端获取资源,如下图所示:

迁移过来,图丢了,文章太老了,懒得补了~~

点击其中的一项,显示出请求和响应的细节信息。

迁移过来,图丢了,文章太老了,懒得补了~~

跟HTTP缓存相关的Header已经被红框标出,这里真正发挥作用Cache-Control和Expires,这两个让浏览器根本不用发请求。浏览器只要发请求就会产生一定的延时,因为即使服务器返回304这样简单的数据,在底层也还需要TCP/IP层的握手等各种操作,而且HTTP协议也会有额外开销。

应用场景

下面罗列了几种场景,并讨论如何设定缓存策略。

静态资源

对于那些不经常改变的静态资源,比如CSS、图片、动画等,应尽可能地利用缓存。因为这些资源通常很大而且几乎每个页面可能都会用到,缓存会大大提高系统效率。对于这些资源,响应中应该包含如下内容:

迁移过来,图丢了,文章太老了,懒得补了~~

max-age=31536000意味着31536000秒(也就是一年)后缓存失效。这里尤为注意不能设置成多于一年,因为RFC上限制了最大只能是一年,超过一年的情况不同的浏览器处理策略不同,有些直接就忽略了Cache-Control。

动态资源

对于动态内容,需要依据内容的实际情况,定义合适的max-age。例如对于SNS网络中的时间线通常可以设置成几秒。

私有内容

对于需要登录才能访问到资源,Cache-Control应该设置成private以禁止代理服务器缓存这些资源,否则会威胁信息安全。

禁用缓存

某些情况下需要禁止使用缓存,则应该把Cache-Control设置成"no-cache, no-store",如下所示。

Cache-Control:no-cache, no-store

相关文章

  • 网站架构

    提升系统性能 扩容 加缓存来提升系统并发能力 使用队列进行流量削峰 异步并发机制提升吞吐量或者接口性能 高并发原则...

  • Redis 缓存使用常见问题及解决方案

    使用缓存,可以有效缓解系统大流量压力,显著提升系统性能,降低数据库的频繁读写压力,Redis 在作为缓存服务使用时...

  • 常用缓存系统使用经验总结

    缓存系统是提升系统性能和处理能力的利器,常用的缓存系统各自的特性和使用场景有所不同,这里总结下常用缓存系统时需要关...

  • 转载:系统性能提升优先法宝 | 缓存应用实践

    转载:系统性能提升优先法宝 | 缓存应用实践 缓存是系统性能提升优先法宝,在互联网应用系统中,屡试不爽。网上有很多...

  • 缓存策略优化

    缓存介绍 在高并发多用户的系统中常常会使用缓存来提升读写性能 常见的如memcached, redis, 内存缓存...

  • HTTP缓存

    缓存是提升页面性能的一项重要技术,而HTTP 缓存技术在我们日常使用浏览器时被广泛应用。 HTTP缓存分为两种类型...

  • 浏览器的缓存机制

    一、缓存机制概述 1. 基本概念介绍 浏览器缓存机制(即HTTP缓存机制),根据HTTP报文的缓存标识来决定使用缓...

  • spring boot使用总结(五) 在spring boot

    在系统中使用缓存,可以加快获取数据的速度,提高系统的效率,是提升系统性能的“银弹”。在spring boot中使用...

  • HTTP 缓存机制

    为了提高浏览器 HTTP 请求的性能,在 HTTP 协议中有几种缓存机制来保证网络访问的性能。HTTP 协议中提供...

  • 缓存和分布式锁

    @[toc] 一、缓存 1、缓存使用 为了系统性能的提升,我们一般都会将部分数据放入缓存中,加速访问。而db承担数...

网友评论

      本文标题:使用 HTTP 缓存机制提升系统性能

      本文链接:https://www.haomeiwen.com/subject/tlqwmdtx.html