Maison > Article > interface Web > Un article pour résoudre la 'mise en cache'
La colonne
La mise en cache signifie : afin de réduire la fréquence d'accès du serveur et de réduire le nombre de communications, le front-end enregistre les informations de données acquises. Les données enregistrées sont à nouveau utilisées lorsque cela est nécessaire.
La mise en cache aura un impact important sur l'expérience utilisateur et les coûts de communication, le mécanisme de mise en cache doit donc être utilisé de la manière la plus flexible possible.
HTTP
Le cache est un cache avec le temps comme dimension.
Le navigateur met en cache la réponse à la première requête, et les requêtes suivantes peuvent récupérer la réponse de la première requête dans le cache. Cela permet de réduire la latence et également la consommation de bande passante, car la requête peut ne pas être envoyée du tout, donc le débit du réseau diminue également.
Le navigateur fait la première requête et le serveur renvoie une réponse. Si la réponse contient des informations indiquant au navigateur que la réponse peut être mise en cache. Le navigateur met ensuite cette réponse en cache dans le cache du navigateur.
Si une demande ultérieure est effectuée, le navigateur déterminera d'abord si le cache a expiré. S'il n'a pas expiré, le navigateur ne fera aucune requête au serveur, mais récupérera le résultat directement depuis le cache.
Par exemple : visitez le site Nuggets
Comme on peut le voir sur Size
, disk cache
sont des informations mises en cache extraites du disque dur.
Si le cache a expiré, le serveur ne renvoie pas nécessairement une réponse directement à la première requête.
Lorsque le temps de cache du navigateur a expiré, la requête sera envoyée au serveur avec une balise de cache. A ce moment, si le serveur estime que le cache est toujours disponible, il renverra un code de réponse 304. Le navigateur continuera à utiliser ce cache.
Par exemple : sélectionnez l'un des fichiers de cache dans l'image ci-dessus, copy
demandez url
à afficher dans curl
ajoutez d'abord -I
pour obtenir la demande d'origine, cochez etag
ou last-modified
Tête.
Car après l'expiration du cache du navigateur, la requête sera envoyée au serveur avec ces en-têtes, permettant au serveur de déterminer si elle peut toujours être utilisée.
Pour l'en-tête etag
, ajoutez un en-tête if-none-match
avec la valeur de etag
pour interroger le serveur. Bien sûr, vous pouvez également ajouter un en-tête last-modified
pour demander l'en-tête if-modified-since
.
renvoie 304. L'avantage de 304 est qu'il ne porte pas le corps du package, ce qui signifie que content-length
vaut 0, ce qui permet d'économiser beaucoup de bande passante.
Le cache du navigateur est un cache privé et n'est disponible que pour un seul utilisateur.
Le cache partagé est placé sur le serveur et peut être utilisé par plusieurs utilisateurs. Par exemple, une vidéo populaire et d'autres ressources chaudes seront placées dans le cache du serveur proxy pour réduire la pression sur le serveur source et améliorer l'efficacité du réseau.
Comment savoir si cette ressource est mise en cache par le serveur proxy ou envoyée par le serveur d'origine ?
Toujours en utilisant l'exemple des Nuggets
Sur la photo, nous pouvons voir l'en-tête Response Headers
dans le age
de cette requête, l'unité est la seconde.
indique que ce cache est renvoyé par le cache partagé. age
indique l'heure à laquelle il existe dans le cache partagé. Le chiffre est 327784, ce qui signifie qu'il existe dans le cache partagé depuis 327784 secondes.
Le cache partagé expire également. Voyons comment fonctionne le cache partagé.
Comme le montre la figure :
1. Lorsque client1
initie une requête, Cache
est le serveur proxy (cache partagé) et transmet la requête au serveur source. Le serveur d'origine renvoie la réponse et la met en cache pendant 100 secondes dans l'en-tête Cache-Control
. Ensuite, un minuteur Cache
sera démarré dans Age
, et la réponse sera renvoyée à Age:0
avec l'en-tête client1
.
2. Après 10 secondes, client2
envoie la même requête. Le cache dans Cache
n'a pas expiré, il renvoie donc la réponse dans le cache à Age:10
avec l'en-tête client2
.
3. Après 100 secondes, client3
envoie la même requête. À ce moment, le cache dans Cache
a expiré. Comme mentionné précédemment, utilisez l'en-tête de requête conditionnelle If-None-Match
pour le mettre en cache. l'empreinte digitale est envoyée au serveur d'origine. Lorsque le service d'origine estime que le cache est toujours disponible, il renvoie un code d'état 304 à Cache
. Cache
resynchronisera, trouvera la réponse du cache et la renverra à Age:0
avec l'en-tête Client3
.
HTTP
Il existe des mécanismes de mise en cache associés dans le protocole, et ces mécanismes peuvent également être utilisés directement dans API
pour gérer le cache. Le mécanisme de mise en cache de HTTP
est défini en détail dans RFC7234
et est divisé en deux catégories : le modèle expiré (Expiration Model)
et le modèle de vérification (Validation Model)
Dans HTTP
, lorsque le cache est disponible, on l'appelle l'état fresh
(frais), et lorsqu'il est indisponible, on l'appelle l'état stale
(périmé).
Le modèle d'expiration peut être implémenté en incluant les informations d'expiration dans le message de réponse du serveur. Deux méthodes d'implémentation sont définies dans HTTP1.1
: une méthode consiste à utiliser Cache-Control
pour répondre à l'en-tête du message, et l'autre méthode consiste à utiliser Expires
pour répondre à l'en-tête du message. L'en-tête
// 1 Expires: Fri, 01 Oct 2020 00:00:00 GMT // 2 Cache-Control: max-age=3600复制代码
Expires
existe depuis HTTP1.0
. Il utilise l'heure absolue pour représenter l'expiration et est décrit en utilisant le format d'heure défini dans RFC1123
. Cache-Control
est défini dans HTTP1.1
et représente le nombre de secondes écoulées depuis l'heure actuelle.
这两个首部该使用哪个,则是由返回的数据的性质决定的。对于一开始就知道在某个特定的日期会更新的数据,比如天气预报这种每天在相同时间进行更新的数据,可以使用Expires
首部来指定执行更新操作的时间。对于今后不会使用更新的数据或静态数据等,可以通过指定一个未来非常遥远的日期,使得获取的缓存数据始终保存下去。但根据HTTP1.1
的规定,不允许设置超过1年以上的时间,因此未来非常遥远的时间最多也只能是1年后的日期了。
Expires: Fri, 01 Oct 2021 00:00:00 GMT复制代码
而对于不是定期更新,但如果更新频率在某种程度上是一定的,或者虽然更新频率不低但不希望频繁访问服务器端,对于这种情况可以使用Cache-Control
首部。
如果Expires
和Cache-Control
首部同时使用时,Cache-Control
首部优先判断。
上面Cache-Control
示例中使用到了max-age
关键字,max-age
计算会使用名为Date
的首部。该首部用来显示服务器端生成响应信息的时间信息。从该时间开始计算,当经过的时间超过max-age
值时,就可以认为缓存已到期。
Date: Expires: Fri, 30 Sep 2020 00:00:00 GMT复制代码
Date
首部表示服务器端生成响应信息的时间信息。根据HTTP
协议的规定,除了几个特殊的情况之外,所有的HTTP
消息都要加上Date
首部。
Date
首部的时间信息必须使用名为HTTP
时间的格式来描述。在计算缓存时间时,会用到该首部的时间信息,这时就可以使用Date
首部信息来完成时间的同步操作,做到即便客户端擅自修改日期等配置信息。
与到期模型只根据所接收的响应信息来决定缓存的保存时间相对,验证模型采用了询问服务器的方式来判断当前时间所保存的缓存是否有效。
验证模型在检查缓存的过程中会不时地去访问网络。在执行验证模型时,需要应用程序服务器支持附带条件地请求。附带条件地请求是指前端向服务器端发送地“如果现在保存地信息有更新,请给我更新后地信息”。在整个处理的过程中,前端会发送同“过去某个时间点所获得的数据”有关的信息,随后只有在服务器端的数据发生更新时,服务器端才会返回更新的数据,不然就只会返回304(Not Modified)
状态码来告知前端当前服务器端没有更新的数据。
要进行附带条件的请求,就必须向服务器端传达“前端当前保存的信息的状态”,为此需要用到最后更新日期或实体标签(Entity Tag)
作为指标。顾名思义,最后更新日期表示当前数据最后一次更新的日期:而实体标签则是表示某个特定资源版本的标识符,十一串表示指纹印(Finger Print)
的字符串。例如响应数据的MD5散列值等,整个字符串会随着消息内容的变化而变化。这些信息会在服务器端生成,并被包含在响应信息的首部发送给前端,前端会将其缓存一同保存下来,用于附带条件的请求。
最后更新日期和实体标签会被分别填充到Last-Modified
和ETag
响应消息首部返回给前端
Last-Modified: Fri, 01 Oct 2021 00:00:00 GMT ETag: 'ff568sdf4545687fadf4dsa545e4f5s4f5se45'复制代码
前端使用最后更新日期执行附带条件的请求时,会用到Modified-Since
首部。在使用实体标签时,会用到If-None-Match
首部
GET /v1/user/1 If-Modified-Since: Fri, 01 Oct 2021 00:00:00 GMT GET /v1/user/1 If-None-Match: 'ff568sdf4545687fadf4dsa545e4f5s4f5se45'复制代码
服务器端会检查前端发送过来的信息和当前信息,如果没有发生更新则返回304状态码。如果有更新,则会同应答普通请求一样,在返回200状态码的同时将更新内容一并返回给前端,这时也会带上新的最后更新日期和实体标签。当服务器返回304状态码时,响应消息为空,从而节约了传输的数据量。
在HTTP
协议中,ETag
有强验证与弱验证两个概念。
执行强验证的ETag
ETag: 'ffsd5f46s12wef13we2f13dsd21fsd32f1'
执行弱验证的ETag
ETag: W/'ffsd5f46s12wef13we2f13dsd21fsd32f1'
强验证是指服务器端同客户端的数据不能有一个字节的差别,必须完全一样;而弱验证是指即使数据不完全一样,只要从资源意义的角度来看没有发生变化,就可以视为相同的数据。例如广告信息,虽然每次访问时这些广告的内容都会有所改变,但它们依然是相同的资源,这种情况下便可以使用弱验证。
HTTP1.1
a mentionné que lorsque le serveur ne donne pas de délai d'expiration clair, le client peut décider combien de temps les données mises en cache doivent être enregistrées. À ce stade, le client doit déterminer le délai d'expiration du cache en fonction de la fréquence de mise à jour du serveur, des conditions spécifiques et d'autres informations. Cette méthode est appelée expiration heuristique.
Par exemple, en observant Last-Modified
sur le front-end, s'il s'avère que la dernière mise à jour remonte à 1 an, cela signifie qu'il n'y aura aucun problème pour sauvegarder les données du cache pendant un certain temps si ; on constate que les données du cache consultées jusqu'à présent. Le résultat est qu'il n'y a qu'une seule mise à jour par jour, ce qui signifie qu'il peut être possible de conserver le cache pendant une demi-journée. Ainsi, le front-end peut réduire le nombre de visites grâce à un jugement indépendant.
Bien que API
le fait que l'expiration heuristique soit autorisée dépend des caractéristiques de l'API, puisque le serveur a la compréhension la plus approfondie de la mise à jour et du contrôle du cache, le serveur utilise Cache-Control
, Expires
, etc. renvoyer des informations sur « la durée de sauvegarde des données mises en cache » au front-end est idéal pour les deux parties. Mais s'il ne revient pas, le serveur doit informer le front-end via des informations d'en-tête telles que Last-Modified
Vary
en même temps lors de l'implémentation de la mise en cache Première partie. Lors de l'implémentation de la mise en cache, Vary
est utilisé pour spécifier quel élément d'en-tête de requête est utilisé en plus de Vary
pour déterminer des données uniques. URI
est utilisé car même si Vary
est le même, les données obtenues changent parfois en raison du contenu différent de l'en-tête de la requête. Seuls les en-têtes spécifiés par l'en-tête URI
doivent correspondre aux en-têtes de la demande de mise en cache à utiliser. La définition de vary
: vary
field-name
1 Lorsque
porte le header Client1
Les demandes sont envoyées à Accept-Encoding:*
. GET
renvoie la réponse codée server
et l'en-tête server
, ce qui signifie que la mise en cache ne peut être utilisée que lorsque la méthode d'encodage est la même. gzip
vary:Content-Encoding
2. Lorsque
avec un en-tête Client2
et l'envoie à Accept-Encoding:br
, la requête est pour l'encodage GET
. Par conséquent, server
ne peut pas utiliser la mise en cache car elle ne correspond pas à la valeur de br
et ne peut transmettre la demande qu'au serveur d'origine Cache
. vary
server
3. Lorsque
portant l'en-tête Client3
et l'envoie à Accept-Encoding:br
, alors GET
dispose d'un cache d'encodage server
qui peut correspondre au Cache
valeur d'en-tête, afin qu'elle puisse être renvoyée en utilisant le cache. br
vary
De manière générale, l'en-tête
devient une option obligatoire. Vary
Vary
Cache-Control
Cache-Control
Cache-Control
token
Facultatif "=", plus la valeur citée ou 1 Un ou plusieurs nombres décimaux, qui sont le nombre de secondes spécifié Cache-Control
Cache-Control
token
2 token
valeur + '=' + en-tête correspondant/ Utiliser directement token
token
dans l'application de requête Age
datant de plus de max-age
secondes max-stale
. S'il n'y a aucune valeur après max-stale
, cela signifie que le client peut l'utiliser quelle que soit sa durée d'expiration. Age
le cache peut être utilisé après au moins min-fresh
secondes dans la réponse La valeur et la signification de Cache-Control
dans :
Age
dépasse max-age
secondes max-age
, mais uniquement pour le cache partagé, et a une priorité plus élevée que max-age
et expires
must-revaildate
, mais il n'est valable que pour le cache partagé du proxy serveur no-cache
, alors si les requêtes et réponses ultérieures du client ne contiennent pas ces en-têtes, le cache peut être utilisé directement priate
, il indique au serveur proxy qu'il ne peut pas mettre en cache l'en-tête spécifié et peut mettre en cache d'autres en-têtes Recommandations d'apprentissage gratuites associées : javascript(vidéo)
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!