Maison >Problème commun >Comment concevoir une stratégie de mise en cache http parfaite

Comment concevoir une stratégie de mise en cache http parfaite

angryTom
angryTomavant
2019-08-20 17:35:543505parcourir

Comment concevoir une stratégie de mise en cache http parfaite

1. Avant-propos

En tant que front-end, il est très nécessaire de comprendre la mise en cache http Ce n'est pas seulement une partie nécessaire de l'entretien, mais aussi un must dans le développement réel.Il y a des points de connaissances essentiels qui doivent être compris.L'auteur de cet article parlera du concept de mise en cache et de la façon de concevoir une architecture de mise en cache raisonnable dans l'entreprise, en vous guidant étape par étape. le mystère de la mise en cache http.

2. Définition du cache http

Lorsque le client demande des ressources au serveur, il atteindra d'abord le cache du navigateur Si le navigateur dispose d'une copie des "Ressources à demander", il peut. parcourir directement depuis La ressource est récupérée depuis le cache du serveur au lieu de la récupérer depuis le serveur d'origine. La mise en cache http est généralement destinée aux requêtes GET, et les requêtes POST ne sont généralement pas mises en cache, car les tâches effectuées par les requêtes POST sont des effets secondaires ou des tâches non idempotentes sur le serveur. Puisque les ressources du serveur doivent être modifiées, la requête doit naturellement entrer dans le serveur. serveur pour le traitement. Les avantages de la mise en cache sont énormes. La réduction des requêtes http réduit naturellement la pression sur le serveur et augmente la vitesse d'accès aux ressources. Cependant, une utilisation aveugle du cache entraînera des mises à jour intempestives des ressources, voire des mises à jour des ressources mal alignées, le désastre est également énorme.
La mise en cache http est divisée en mise en cache forte et mise en cache négociée. Examinons les deux mécanismes de mise en cache un par un.

3. Mise en cache forte

3.1. Définition de mise en cache forte

Si le cache est touché, les données seront récupérées directement depuis le cache. serveur, et le code d'état http renvoyé est 200 (à partir du cache disque)

Comment concevoir une stratégie de mise en cache http parfaite

Ce qui suit est un organigramme pour illustrer le processus de demande de cache fort. Pour plus de commodité, il est supposé. que le navigateur dispose d'une base de données de cache (en fait un disque. Où les données mises en cache sont stockées).

Comment concevoir une stratégie de mise en cache http parfaite

Comment concevoir une stratégie de mise en cache http parfaite

Regardez attentivement l'organigramme ci-dessus. La plus grande caractéristique de la mise en cache forte est qu'elle ne passera pas par le serveur. lorsque le cache est atteint, mais revient directement.

3.2. L'en-tête Http Expires/Cache-Control définit un cache fort

Il existe plusieurs attributs dans Cache-Control pour contrôler le cache. Définir la période de validité des ressources. max-age .
Permettez-moi de démontrer cela en utilisant Express

app.get('/script1.js', function (req, res, next) {  
  // res.header('Cache-Control', 'must-revalidate, max-age=600')    
  // res.header('Content-Type', 'text/html')
    res.header('Cache-Control', 'max-age=20')
    res.sendFile(__dirname + '/script.js')
})

Comment concevoir une stratégie de mise en cache http parfaite

Expires et max-age sont tous deux utilisés pour contrôler le cycle de vie du cache. La différence est que Expires spécifie l'heure d'expiration spécifique, par exemple dimanche 21 mars 2027 08:52:14 GMT, tandis que max-age spécifie les secondes de durée de vie de 315360000.

La différence est que Expires est une norme dans HTTP/1.0, tandis que max-age est le contenu de Cache-Control et est défini dans HTTP/1.1. Mais pour des raisons de compatibilité ascendante, ces deux attributs doivent toujours exister en même temps. max-age a priorité sur Expires.

4. Mise en cache de négociation/comparaison

4.1. Définition

La différence entre la mise en cache de négociation et la mise en cache forcée est que le cache de négociation doit communiquer avec le serveur à chaque fois qu'il lit. la communication et l'ID du cache seront ajoutés. Lors de la première demande au serveur, le serveur renverra la ressource et renverra un identifiant de cache de la ressource, qui sera stocké dans la base de données cache du navigateur. Lors de la deuxième demande d'une ressource, le navigateur enverra d'abord l'identifiant du cache au serveur. Une fois que le serveur aura obtenu l'identifiant, il déterminera si l'identifiant correspond. S'il ne correspond pas, cela signifie que la ressource a été mise à jour. , et le serveur renverra les nouvelles données et le nouvel identifiant de cache au navigateur ; si l'identifiant de cache correspond, cela signifie que la ressource n'a pas été mise à jour, et un code d'état 304 est renvoyé, et le navigateur lit les données dans. le serveur de cache local.

La plus grande caractéristique du cache de négociation est qu'il doit être vérifié par le serveur. Expliquons le processus de vérification du cache de négociation.

Première visite :

Comment concevoir une stratégie de mise en cache http parfaite

Revisite :

Comment concevoir une stratégie de mise en cache http parfaite

Laissez-moi vous donner vous un organigramme pour illustrer. (La photo est volée, le cache de négociation peut aussi être un cache de comparaison, le cache de comparaison sur la photo est le cache de négociation)
Comment concevoir une stratégie de mise en cache http parfaite

4.2、协商缓存如何验证

  第一次请求将response header的Last-Modified和Etag存起来,在第二次请求通过request header的If-Modified-Since和If-None-Match传到服务端进行验证,如果命中缓存,返回304,不带返回的数据,浏览器自动从缓存中获取数据资源,若未命中缓存返回200,带上数据资源。

** Last-Modified:**

服务器在响应请求时,告诉浏览器资源的最后修改时间。

Comment concevoir une stratégie de mise en cache http parfaite

** If-Modified-Since:**

再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。

服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。

若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;

若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

Comment concevoir une stratégie de mise en cache http parfaite

** Etag / If-None-Match(优先级高于Last-Modified / If-Modified-Since) **

** Etag:**

服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。

Comment concevoir une stratégie de mise en cache http parfaite

** If-None-Match:**

再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。

服务器收到请求后发现有头If-None-Match 则与被请求资源的唯一标识进行比对,

不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;

相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

Comment concevoir une stratégie de mise en cache http parfaite

4.3、Http头如何设置协商缓存

  在强缓存那一节说到使用Cache-Control的max-age来设置资源过期时间,那么当max-age=0的时候呢,自然浏览器第一时间发现资源过期,request header就会带着If-Modified-Since和If-None-Match去服务端验证。
所以设置response header为:

Cache-Control: max-age=0

  就可以触发协商缓存了,其实Cache-Control中还有两个属性都可以设置协商缓存 must-revalidate和no-cache
must-revalidate的意义为必须进行验证,但是它一般是和max-age一起使用的,不会单独使用,

Cache-Control: must-revalidate, max-age=600

  该头信息意义就是在资源有效期过后必须进行验证, 与只设置max-age=600的区别是,前面一个是MUST,而后面一个是SHOULD,理论上来说它们的效果是一致的。

  no-cache的意义千万不能理解为不缓存,下面两段代码的意义是一样的,即请求必须进行验证,才可以使用缓存资源,注意是MUST

Cache-Control: no-cacheCache-Control: must-revalidate, max-age=0

  如果要不缓存,每次都请求新的资源应该使用

Cache-Control: no-store

5、关于缓存的Http头总结

5.1、"no-cache", "no-store", "must-revalidate"

  Cache-Control字段可以设置的不仅仅是max-age存储时间,还有其他额外的值可以填写,甚至可以组合。主要使用的值有如下:

  no-cache: 虽然字面意义是“不要缓存”。但它实际上的机制是,仍然对资源使用缓存,但每一次在使用缓存之前必须(MUST)向服务器对缓存资源进行验证。

  no-store: 不使用任何缓存

  must-revalidate: 如果你配置了max-age信息,当缓存资源仍然新鲜(小于max-age)时使用缓存,否则需要对资源进行验证。所以must-revalidate可以和max-age组合使用Cache-Control: must-revalidate, max-age=60

  有趣的事情是,虽然no-cache意为对缓存进行验证,但是因为大家广泛的错误的把它当作no-store来使用,所以有的浏览器也就附和了这种设计。这是一个典型的劣币驱逐良币。

5.2、Expires VS. max-age

  Expires和max-age都是用于控制缓存的生命周期。不同的是Expires指定的是过期的具体时间,例如Sun, 21 Mar 2027 08:52:14 GMT,而max-age指定的是生命时长秒数315360000。

  区别在于Expires是 HTTP/1.0 的中的标准,而max-age是属于Cache-Control的内容,是 HTTP/1.1 中的定义的。但为了想向前兼容,这两个属性仍然要同时存在。

  但有一种更倾向于使用max-age的观点认为Expires过于复杂了。例如上面的例子Sun, 21 Mar 2027 08:52:14 GMT,如果你在表示小时的数字缺少了一个0,则很有可能出现出错;如果日期没有转换到用户的正确时区,则有可能出错。这里出错的意思可能包括但不限于缓存失效、缓存生命周期出错等。

5.3、Etag VS. Last-Modified

  Etag和Last-Modified都可以用于对资源进行验证,而Last-Modified顾名思义,表示资源最后的更新时间。

  我们把这两者都成为验证器(Validators),不同的是,Etag属于强验证(Strong Validation),因为它期望的是资源字节级别的一致;而Last-Modified属于弱验证(Weak Validation),只要资源的主要内容一致即可,允许例如页底的广告,页脚不同。

  根据RFC 2616标准中的13.3.4小节,一个使用HTTP 1.1标准的服务端应该(SHOULD)同时发送Etag和Last-Modified字段。同时一个支持HTTP 1.1的客户端,比如浏览器,如果服务端有提供Etag的话,必须(MUST)首先对Etag进行Conditional Request(If-None-Match头信息);如果两者都有提供,那么应该(SHOULD)同时对两者进行Conditional Request(If-Modified-Since头信息)。如果服务端对两者的验证结果不一致,例如通过一个条件判断资源发生了更改,而另一个判定资源没有发生更改,则不允许返回304状态。但话说回来,是否返回还是通过服务端编写的实际代码决定的。所以仍然有操纵的空间。

5.4、max-age=0 VS. no-cache

  max-age=0是在告诉浏览器,资源已经过期了,你应该(SHOULD)对资源进行重新验证了;而no-cache则是告诉浏览器在每一次使用缓存之前,你必须(MUST)对资源进行重新验证。

  区别在于,SHOULD是非强制性的,而MUST是强制性的。在no-cache的情况下,浏览器在向服务器验证成功之前绝不会使用过期的缓存资源,而max-age=0则不一定了。虽然理论上来说它们的效果应该是一致的。

5.5、public VS. private

  要知道从服务器到浏览器之间并非只有浏览器能够对资源进行缓存,服务器的返回可能会经过一些中间(intermediate)服务器甚至甚至专业的中间缓存服务器,还有CDN。而有些请求返回是用户级别、是私人的,所以你可能不希望这些中间服务器缓存返回。此时你需要将Cache-Control设置为private以避免暴露。

6、缓存实战

  前面写了很多缓存的基础知识,那么如何设计一个可靠的缓存规则,这个其实得根据你的实际需求而定。

  比如某个资源永远不会改变,比如某些第三方库(一般都放CDN做优化了),或者某些图片,比如百度的图片,就让它们永久缓存着吧,设置一个最大的max-age

Cache-Control: max-age=31536000

其他的资源可根据下面这张决策树来进行设置

Comment concevoir une stratégie de mise en cache http parfaite

7、memory cache

Comment concevoir une stratégie de mise en cache http parfaite

  “内存缓存”中主要包含的是当前文档中页面中已经抓取到的资源。例如页面上已经下载的样式、脚本、图片等。我们不排除页面可能会对这些资源再次发出请求,所以这些资源都暂存在内存中,当用户结束浏览网页并且关闭网页时,内存缓存的资源会被释放掉。

  这其中最重要的缓存资源其实是preloader相关指令(例如)下载的资源。总所周知preloader的相关指令已经是页面优化的常见手段之一,而通过这些指令下载的资源也都会暂存到内存中。根据一些材料,如果资源已经存在于缓存中,则可能不会再进行preload。

  需要注意的事情是,内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验
这个应该是浏览器做的一种优化,缓存也只是暂时的。

8. Le navigateur peut restreindre l'en-tête Cache-Control non valide

Comment concevoir une stratégie de mise en cache http parfaite

Tutoriel recommandé : Manuel de développement HTTP en chinois

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer