Caching bedeutet: Um die Zugriffshäufigkeit des Servers zu reduzieren und die Anzahl der Kommunikationen zu reduzieren, speichert das Frontend die erfassten Dateninformationen und verwendet die gespeicherten Daten, wenn sie wieder benötigt werden.
Caching hat große Auswirkungen auf die Benutzererfahrung und die Kommunikationskosten. Nutzen Sie den Caching-Mechanismus daher so flexibel wie möglich.
HTTP
-Cache ist ein Cache mit der Dimension Zeit. HTTP
缓存是一个以时间为维度的缓存。
浏览器在第一次请求中缓存了响应,而后续的请求可以从缓存提取第一次请求的响应。从而达到:减少时延而且还能降低带宽消耗,因为可能压根就没有发出请求,所以网络的吞吐量也下降了。
浏览器发出第一次请求,服务器返回响应。如果得到响应中有信息告诉浏览器可以缓存此响应。那么浏览器就把这个响应缓存到浏览器缓存中。
如果后续再发出请求时,浏览器会先判断缓存是否过期。如果没有过期,浏览器压根就不会向服务器发出请求,而是直接从缓存中提取结果。
比如:访问掘金站点
从Size
中可以看出,disk cache
Der Browser stellt die erste Anfrage und der Server gibt eine Antwort zurück. Wenn die Antwort Informationen enthält, die dem Browser mitteilen, dass die Antwort zwischengespeichert werden kann. Anschließend speichert der Browser diese Antwort im Browser-Cache.
Bei einer nachfolgenden Anfrage stellt der Browser zunächst fest, ob der Cache abgelaufen ist. Wenn es nicht abgelaufen ist, stellt der Browser überhaupt keine Anfrage an den Server, sondern holt sich das Ergebnis direkt aus dem Cache.
🎜Zum Beispiel: Besuchen Sie die Nuggets-Website🎜🎜Wie ausSize
ersichtlich ist, handelt es sich bei Disk Cache
um Cache-Informationen, die von der Festplatte extrahiert werden. 🎜🎜Der Cache ist abgelaufen🎜🎜Wenn der Cache abgelaufen ist, gibt der Server möglicherweise nicht unbedingt eine Antwort direkt wie bei der ersten Anfrage zurück. 🎜🎜Wenn die Cache-Zeit des Browsers abgelaufen ist, wird die Anfrage mit einem Cache-Tag an den Server gesendet. Wenn der Server zu diesem Zeitpunkt der Meinung ist, dass der Cache noch verfügbar ist, gibt er einen 304-Antwortcode zurück. Der Browser verwendet diesen Cache weiterhin. 🎜Zum Beispiel: Wählen Sie eine der Cache-Dateien im Bild oben aus, copy
fordert url
an und zeigt die Klasse curlan > ="lazyload" src="https://img.php.cn/upload/article/000/000/052/ae32126dc9ee893cffdb71d59665b5a9-1.png" data-width="800" data- style="max-width:90%"/> Fügen Sie zunächst -I
hinzu, um die ursprüngliche Anfrage zu erhalten, und überprüfen Sie den Header etag
oder last-modified
. copy
请求url
在curl
中展示
首先加-I
获取原始请求,查看etag
或last-modified
头部。
因为浏览器缓存过期之后,请求就会带上这些头部一起发送给服务器,让服务器判断是否还能用。
针对etag
头部,加一个if-none-match
头部带上etag
的值询问服务器。当然也可以针对last-modified
头部,加一个if-modified-since
头部询问。
返回的是304。304的好处就是不携带包体,也就是说content-length
为0,这样就节省了大量的带宽。
浏览器缓存是私有缓存,只提供给一个用户使用的。
而共享缓存是放在服务器上的,可以提供多个用户使用。比如说某个比较热点的视频等热点资源就会放在代理代理服务器的缓存中,以减低源服务器的压力,提升网络效率。
怎么分辨这个资源是代理服务器的缓存还是源服务器发送的呢?
仍然使用掘金的例子
从图中看出这个请求的Response Headers
中的age
头部,单位是秒。
说明这个缓存是共享缓存返回的,age
说明了它在共享缓存存在的时间,图中是327784,也就是在共享缓存中存在了327784秒。
共享缓存也有过期的时候,下面看看共享缓存的工作原理。
如图所示:
1、当client1
发起请求时,Cache
也就是代理服务器(共享缓存),转发这条请求给源服务器。源服务器返回响应,并在Cache-Control
头部中设定可以缓存100秒。接着在Cache
中就会开启一个定时器Age
,将响应带上Age:0
头部返回给client1
。
2、过了10秒后,client2
发送相同的请求,Cache
中的缓存还没有过期,就带上Age:10
头部返回缓存中的响应给client2
。
3、过了100秒后,client3
发送同样的请求,这时Cache
中的缓存已经过期了,就像前面说到那样用条件请求头部If-None-Match
带上缓存的指纹发给源服务器。当源服务认为此缓存还能用,就返回304状态码给Cache
。Cache
就重新计时,从缓存中找出响应带上Age:0
头部返回给Client3
。
HTTP
协议中存在相关的缓存机制,API
中也可以直接使用这些机制来管理缓存。HTTP
的缓存机制在RFC7234
中进行了详细的定义,分为:过期模型(Expiration Model)
和验证模型(Validation Model)
两类
在HTTP
中,缓存处于可用的状态时称为fresh
(新鲜)状态,而处于不可用的状态时则称为stale
(不新鲜)状态。
过期模型可以通过服务器的响应消息里包含何时过期的信息来实现。HTTP1.1
中定义了两种实现方法:一个方法是用Cache-Control
响应消息首部,另一个方法就是用Expires
响应消息首部。
// 1 Expires: Fri, 01 Oct 2020 00:00:00 GMT // 2 Cache-Control: max-age=3600复制代码
Expires
首部从HTTP1.0
就已经存在了,它是用绝对时间来表示到期,并使用RFC1123
中定义的时间格式来描述。Cache-Control
则是HTTP1.1
etag
einen Header if-none-match
mit dem Wert von etag
hinzu, um den Server abzufragen. Natürlich können Sie auch einen if-modified-since
-Header hinzufügen, um nach dem last-modified
-Header zu fragen. content-length
0 ist , was viel Geld spart. 🎜age
in den Response Headers
von sehen diese Anfrage. Kopf, Einheit ist Sekunden. 🎜🎜Gibt an, dass dieser Cache vom gemeinsam genutzten Cache zurückgegeben wird. age
gibt die Zeit an, die er im gemeinsam genutzten Cache vorhanden ist. Der Wert ist 327784, was bedeutet, dass er seit 327784 Sekunden im gemeinsam genutzten Cache vorhanden ist. 🎜🎜Der Shared Cache läuft ebenfalls ab. Schauen wir uns an, wie der Shared Cache funktioniert. client1
eine Anfrage initiiert, ist Cache
der Proxy Der Server (gemeinsamer Cache) leitet diese Anfrage an den Ursprungsserver weiter. Der Ursprungsserver gibt die Antwort zurück und legt die Cache-Zeit im Header Cache-Control
auf 100 Sekunden fest. Dann wird ein Timer Alter
im Cache
gestartet und die Antwort wird an client1
mit dem Alter: 0
zurückgegeben > Kopfzeile. Code>. 🎜🎜2. Nach 10 Sekunden sendet client2
die gleiche Anfrage. Der Cache im Cache
ist nicht abgelaufen, daher wird Alter: 10
angezeigt Der Header gibt die zwischengespeicherte Antwort an client2
zurück. 🎜🎜3. Nach 100 Sekunden sendet client3
die gleiche Anfrage. Zu diesem Zeitpunkt ist der Cache in Cache
abgelaufen Der Code>If-None-Match-Teil trägt den zwischengespeicherten Fingerabdruck und sendet ihn an den Ursprungsserver. Wenn der Ursprungsdienst davon ausgeht, dass der Cache noch verfügbar ist, gibt er einen 304-Statuscode an Cache
zurück. Cache
führt ein Retime durch, findet die Antwort aus dem Cache und gibt sie mit dem Header Age: 0
an Client3
zurück. 🎜HTTP
-Protokoll, und diese können auch direkt in der API Mechanismus zum Verwalten des Caches. Der Caching-Mechanismus von <code>HTTP
ist im Detail in RFC7234
definiert und unterteilt in: Ablaufmodell (Expiration Model)
und Verifizierungsmodell ( Validierungsmodell)
Zwei Typen🎜HTTP
in einem verfügbaren Zustand befindet, wird er als fresh
(frischer) Zustand bezeichnet, und wenn er sich in befindet ein nicht verfügbarer Zustand, wird er als „Ist stale
(nicht frisch)“ bezeichnet. 🎜HTTP1.1
sind zwei Implementierungsmethoden definiert: Eine Methode besteht darin, Cache-Control
zu verwenden, um auf den Nachrichtenheader zu antworten, und die andere Methode besteht darin, Expires zu verwenden
um auf den Nachrichtenkopf zu antworten. 🎜Expires: Fri, 01 Oct 2021 00:00:00 GMT复制代码
Expires
existiert seit HTTP1.0
. Er verwendet die absolute Zeit zur Darstellung des Ablaufs und ist zur Beschreibung im RFC1123
-Zeitformat definiert . Cache-Control
ist in HTTP1.1
definiert und stellt die Anzahl der Sekunden dar, die seit dem aktuellen Zeitpunkt vergangen sind. 🎜这两个首部该使用哪个,则是由返回的数据的性质决定的。对于一开始就知道在某个特定的日期会更新的数据,比如天气预报这种每天在相同时间进行更新的数据,可以使用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
erwähnte, dass der Client entscheiden kann, wie lange die zwischengespeicherten Daten gespeichert werden müssen, wenn der Server keine klare Ablaufzeit angibt. Zu diesem Zeitpunkt muss der Client die Cache-Ablaufzeit basierend auf der Aktualisierungshäufigkeit des Servers, bestimmten Bedingungen und anderen Informationen bestimmen. Diese Methode wird als heuristischer Ablauf bezeichnet. HTTP1.1
里提到了当服务器端没有给出明确的过期时间时,客户端可以决定大约需要将缓存数据保存多久。这时客户端就要根据服务器端的更新频率、具体状况等信息,自行决定缓存的过期时间,这个方法称为启发式过期。
例如前端通过观察Last-Modified
,如果发现最后一次更新是在1年前,那就意味着再将缓存数据保存一段时间也不会有什么问题;如果发现到目前为止访问的结果是1天只有1次更新,那就意味着将缓存保存半天的时间或许可行。像这样,前端能通过独立判断来减少访问次数。
虽然API
是否允许使用启发式过期的方法取决于API的特性,但由于服务端对缓存的更新和控制理解最为深刻,因此服务器端通过Cache-Control
、Expires
等准确无误地向前端返回“将缓存数据保存多久”的信息,对于交互双方而言都是比较理想的做法。但如果不返回,服务器端就需要通过Last-Modified
等首部信息来告知前端
Vary
指定缓存单位在实施缓存时可能还需要同时指定Vary
首部。在实施缓存时,Vary
用于指定除URI
外使用哪个请求首部项目来确定唯一的数据。使用Vary
是因为即使URI
相同,获取的数据有时也会因请求首部内容的不同而发生变化。只有vary
头部指定的头部必须与请求中的头部相匹配才能使用缓存。
vary
的定义:
field-name
:指定的头部必须与请求中的头部相匹配才能使用缓存如图所示:
1、 当Client1
携带Accept-Encoding:*
头部的GET
请求发送给server
。server
返回的是gzip
编码的响应,以及vary:Content-Encoding
头部,表示着编码方式一样的时候才能使用缓存。
2、当Client2
携带Accept-Encoding:br
头部的GET
请求发送给server
,这时请求的是br
编码。所以Cache
不能使用缓存,因为不匹配vary
的中的值,只能转发请求给源服务器server
。
3、当Client3
携带Accept-Encoding:br
头部的GET
请求发送给server
,这时Cache
有br
编码的缓存,能匹配vary
头部的值,所以能使用缓存返回。
一般而言,Vary
首部用于HTTP经由代理服务器进行交互的场景,特别是在代理服务器拥有缓存功能时。但是有时服务端无法得知前端的访问是否经由代理服务器,这种情况下就需要用到服务器驱动的内容协商机制,Vary
首部也就成了必选项。
Cache-Control
头部取值范围非常复杂。
Cache-Control
的定义是:
token
值Cache-Control
既可以在请求中使用,也可以在响应是使用。而且相同的值在请求和响应中的含义是不一样的。
Cache-Control
值有三种用法:
token
token
值+ '=' + 十进制数字token
值+ '=' + 相应的头部 / 直接使用token
值在请求中Cache-Control
Last-Modified
beobachtet und feststellt, dass die letzte Aktualisierung vor einem Jahr erfolgte, bedeutet dies, dass es kein Problem gibt, wenn die Cache-Daten für eine Weile gespeichert werden; wenn es bisher gefunden wurde Das Ergebnis des bisherigen Zugriffs ist, dass es nur ein Update pro Tag gibt, was bedeutet, dass es möglich sein kann, den Cache einen halben Tag lang zu speichern. Auf diese Weise kann das Frontend durch unabhängige Beurteilung die Anzahl der Besuche reduzieren. 🎜🎜Obwohl API
die Verwendung eines heuristischen Ablaufs zulässt, hängt es von den Eigenschaften der API ab, da der Server über das tiefste Verständnis der Cache-Aktualisierung und -Steuerung verfügt, verwendet der Server Cache-Control code>, <code>Expires
usw. geben genaue Informationen darüber zurück, „wie lange die zwischengespeicherten Daten gespeichert werden sollen“ an das Frontend, was für beide Parteien ein idealer Ansatz ist. Wenn es jedoch nicht zurückkehrt, muss der Server das Front-End über Header-Informationen wie Last-Modified
informieren. 🎜Vary code> zur Angabe der Cache-Einheiten 🎜🎜 Möglicherweise muss bei der Implementierung des Cachings auch der Header <code>Vary
angegeben werden. Bei der Implementierung von Caching wird Vary
verwendet, um anzugeben, welches Anforderungsheaderelement zusätzlich zu URI
verwendet wird, um eindeutige Daten zu ermitteln. Vary
wird verwendet, da sich die erhaltenen Daten manchmal aufgrund unterschiedlicher Inhalte des Anforderungsheaders ändern, selbst wenn der URI
derselbe ist. Nur die durch den Header vary
angegebenen Header müssen mit den Headern in der Anforderung übereinstimmen, damit Caching verwendet werden kann. 🎜🎜vary
-Definition: 🎜field-name
: Der Der angegebene Header muss mit dem Header in der Anfrage übereinstimmen, um Caching zu verwendenClient1
sendet die GET
-Anfrage mit dem Accept-Encoding:*
-Header an den server
. server
gibt eine gzip
-codierte Antwort und einen vary: Content-Encoding
-Header zurück, was darauf hinweist, dass Caching nur verwendet werden kann, wenn die Codierungsmethode dieselbe ist . 🎜🎜2. Wenn Client2
die GET
-Anfrage des Accept-Encoding: br
-Headers überträgt und an server
sendet, this Die angeforderte Kodierung ist br
. Daher kann Cache
kein Caching verwenden, da es nicht mit dem Wert in vary
übereinstimmt und die Anfrage nur an den Quellserver server
weiterleiten kann. 🎜🎜3. Wenn Client3
die GET
-Anfrage des Accept-Encoding: br
-Headers überträgt und an server
sendet, Wenn Cache
über einen mit br
codierten Cache verfügt, kann dieser mit dem Wert des Headers vary
übereinstimmen, sodass er über den Cache zurückgegeben werden kann. 🎜🎜Im Allgemeinen wird der Header Vary
in Szenarien verwendet, in denen HTTP über einen Proxyserver interagiert, insbesondere wenn der Proxyserver über eine Caching-Funktion verfügt. Manchmal kann der Server jedoch nicht wissen, ob der Front-End-Zugriff über den Proxyserver erfolgt. In diesem Fall muss der servergesteuerte Inhaltsaushandlungsmechanismus verwendet werden, und der Header Vary
wird zu einer erforderlichen Option . 🎜Cache-Control
Der Wertebereich des Headers ist sehr komplex. 🎜🎜Cache-Control
ist definiert als: 🎜token
-WertCache-Control
kann sowohl in Anfragen als auch in Antworten verwendet werden. Und derselbe Wert hat in der Anfrage und Antwort unterschiedliche Bedeutungen. 🎜🎜Cache-Control
-Wert hat drei Verwendungszwecke: 🎜token
tokenvalue + '=' + Dezimalzahl
token
value + '=' + entsprechender Header/ token
value direkt verwenden li>Cache-Control
in der Anfrage: @ Das Folgende zeigt, wie um es zu benutzen🎜Alter
max-age
Sekunden überschreitet. Age
超出max-age
秒的缓存max-stale
时,客户端仍打算使用。若max-stale
后没有值,则表示无论过期多久,客户端都可使用。Age
至少经过min-fresh
秒后缓存才可使用在响应中Cache-Control
的取值及其含义:
Age
超出max-age
秒后则缓存过期max-age
类似,但仅针对共享缓存,且优先级高于max-age
和expires
must-revaildate
类似,但它仅对代理服务器的共享缓存有效no-cache
后指定头部,则若客户端的后续请求及响应中不含有这些头部则可直接使用缓存priate
max-stale
nicht überschreitet. Wenn nach max-stale
kein Wert steht, bedeutet dies, dass der Client ihn verwenden kann, unabhängig davon, wie lange er abläuft. min-fresh@2: Teilen Sie dem Server mit, dass🎜max-age@2: Teilen Sie dem Client mit, dass der Cache abläuft, nachdemAge
mindestensmin-fresh
Sekunden vergehen muss, bevor der Cache verwendet werden kannno-cache@1: Teilen Sie dem Server mit, dass er nicht direkt verwendet werden kann. Verwenden Sie den vorhandenen Cache als Antwort, es sei denn, Sie gehen mit Caching-Bedingungen zum Upstream-Server und erhalten einen 304-Statuscode. no-store@1: Weisen Sie jeden Proxyserver an, die Antwort auf diese Anfrage nicht zwischenzuspeichern. no-transform@1: Weisen Sie den Proxyserver an, den Inhalt des Nachrichtentexts nicht zu ändern @1: Teilen Sie dem Server mit, dass nur zwischengespeicherte Antworten zurückgegeben werden können. Andernfalls wird ein 504-Fehlercode zurückgegeben, wenn kein Cache vorhanden ist.
Anwendung als Antwort
In AntwortCache-Control und seine Bedeutung:
Age
max- überschreitet. Alter
Sekunden 🎜🎜s -maxage@2: Ähnlich wie max-age
, aber nur für gemeinsam genutzten Cache und hat eine höhere Priorität als max-age
und expires
🎜🎜 must-revaildate@1: Teilen Sie dem Client mit, dass er sich nach Ablauf des Caches beim Server verifizieren muss, bevor er verwendet werden kann 🎜🎜proxy-revalidate@1: Ähnlich wie must-revaildate
, aber es teilt nur den Proxyserver. Der Cache ist gültig🎜🎜no-cache@3: 1. Teilen Sie dem Client mit, dass die zwischengespeicherte Antwort nicht direkt verwendet werden kann. Sie muss auf dem Quellserver überprüft werden Fordern Sie vor der Verwendung einen 304-Rückgabecode an. 2. Wenn nach no-cache
Header angegeben werden, kann der Cache direkt verwendet werden, wenn die nachfolgenden Anforderungen und Antworten des Clients diese Header nicht enthalten. 🎜🎜no-store@1: Informieren Sie alle Downstream-Server Die Antwort kann jedoch nicht zwischengespeichert werden. 3: 1. Zeigt an, dass diese Antwort vom Proxyserver nicht als gemeinsam genutzter Cache verwendet werden kann. 2. Wenn nach priate
ein Header angegeben wird, teilt er dem Proxyserver mit, dass er den angegebenen Header nicht zwischenspeichern kann und andere Header zwischenspeichern kann 🎜(Video)🎜🎜🎜
Das obige ist der detaillierte Inhalt vonEin Artikel zur Lösung von „Caching'. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!