Wir alle wissen, dass die Leistung von Anwendungen und Websites ein entscheidender Faktor für ihren Erfolg ist. Der Prozess zur Verbesserung der Leistung Ihrer Anwendung oder Website ist jedoch nicht immer klar. Natürlich sind Codequalität und Infrastruktur von entscheidender Bedeutung, aber in vielen Fällen können Sie das Endbenutzererlebnis Ihrer Anwendung erheblich verbessern, indem Sie sich auf einige sehr grundlegende Techniken zur Anwendungsbereitstellung konzentrieren. Ein solches Beispiel ist die Implementierung und Optimierung des Caching in Ihrem Anwendungsstapel. In diesem Blogbeitrag werden Techniken behandelt, mit denen sowohl Anfänger als auch fortgeschrittene Benutzer durch die Nutzung der in NGINX und NGINX Plus enthaltenen Inhaltscachefunktionen eine bessere Leistung erzielen können.
Ein Inhaltscache befindet sich zwischen einem Client und einem „Ursprungsserver“ und speichert Kopien aller Inhalte, die er sieht. Wenn ein Client Inhalte anfordert, die im Cache gespeichert sind, gibt er die Inhalte direkt zurück, ohne Kontakt mit dem Ursprungsserver aufzunehmen. Dadurch verbessert sich die Leistung, da sich der Inhaltscache näher am Client befindet, und die Anwendungsserver werden effizienter genutzt, da sie die Seiten nicht jedes Mal von Grund auf neu generieren müssen.
Zwischen dem Webbrowser und dem Anwendungsserver gibt es möglicherweise mehrere Caches: den Browser-Cache des Clients, Zwischen-Caches, Content Delivery Networks (CDNs) und den Load Balancer oder Reverse-Proxy, der den Anwendungsservern vorgeschaltet ist. Durch das Caching kann die Leistung sogar auf der Ebene des Reverse-Proxys/Load Balancers erheblich verbessert werden.
Letztes Jahr habe ich beispielsweise die Aufgabe übernommen, die Leistung einer Website zu optimieren, die langsam geladen wurde. Eines der ersten Dinge, die mir auffielen, war, dass das Generieren der Haupt-Homepage über eine Sekunde dauerte. Nach einigem Debuggen stellte ich fest, dass die Seite, da sie als nicht zwischenspeicherbar markiert war, als Antwort auf jede Anfrage dynamisch generiert wurde. Die Seite selbst änderte sich nicht sehr oft und war nicht personalisiert, daher war dies nicht notwendig. Als Experiment habe ich markiert, dass die Startseite vom Load Balancer 5 Sekunden lang zwischengespeichert werden soll. Allein dies führte zu einer spürbaren Verbesserung. Die Zeit bis zum ersten Byte verringerte sich auf wenige Millisekunden und die Seite wurde sichtbar schneller geladen.
NGINX wird häufig als Reverse-Proxy oder Load Balancer in einem Anwendungsstapel eingesetzt und verfügt über einen vollständigen Satz von Caching-Funktionen. Im nächsten Abschnitt wird die Konfiguration des grundlegenden Caching mit NGINX erläutert.
Zum Aktivieren des grundlegenden Caching sind nur zwei Anweisungen erforderlich: proxy_cache_path
und proxy_cache
. Die Direktive „proxy_cache_path“
legt den Pfad und die Konfiguration des Caches fest und die Direktive „proxy_cache“
aktiviert ihn.
proxy_cache_path /Pfad/zum/Cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { # ... location / { proxy_cache my_cache; proxy_pass http://my_upstream; } }
Die Parameter der Direktive proxy_cache_path
definieren die folgenden Einstellungen:
levels
richtet eine zweistufige Verzeichnishierarchie unter /path/to/cache/ ein. Eine große Anzahl von Dateien in einem einzigen Verzeichnis kann den Dateizugriff verlangsamen. Daher empfehlen wir für die meisten Bereitstellungen eine zweistufige Verzeichnishierarchie. Wenn der Ebenenparameter
nicht enthalten ist, legt NGINX alle Dateien im selben Verzeichnis ab.keys_zone
richtet eine gemeinsam genutzte Speicherzone zum Speichern der Cache-Schlüssel und Metadaten wie Nutzungstimer ein. Wenn eine Kopie der Schlüssel im Speicher vorhanden ist, kann NGINX schnell feststellen, ob es sich bei einer Anforderung um einen Treffer
oder einen Fehlschlag
handelt, ohne auf die Festplatte zugreifen zu müssen. Dadurch wird die Prüfung erheblich beschleunigt. Eine 1-MB-Zone kann Daten für etwa 8.000 Schlüssel speichern. Die im Beispiel konfigurierte 10-MB-Zone kann also Daten für etwa 80.000 Schlüssel speichern.max_size
legt die Obergrenze der Cachegröße fest (in diesem Beispiel auf 10 Gigabyte). Dies ist optional. Wenn Sie keinen Wert angeben, kann der Cache so erweitert werden, dass der gesamte verfügbare Speicherplatz genutzt wird. Wenn die Cachegröße das Limit erreicht, entfernt ein Prozess namens Cache-Manager die zuletzt verwendeten Dateien, um die Cachegröße wieder unter das Limit zu bringen.„inaktiv“
gibt an, wie lange ein Element im Cache verbleiben kann, ohne dass darauf zugegriffen wird. In diesem Beispiel wird eine Datei, die 60 Minuten lang nicht angefordert wurde, vom Cache-Manager-Prozess automatisch aus dem Cache gelöscht, unabhängig davon, ob sie abgelaufen ist oder nicht. Der Standardwert beträgt 10 Minuten ( 10 m
). Inaktiver Inhalt unterscheidet sich von abgelaufenem Inhalt. NGINX löscht nicht automatisch Inhalte, die gemäß der Definition eines Cache-Control-Headers (z. B. Cache-Control:max-age=120
) abgelaufen sind. Abgelaufene (veraltete) Inhalte werden nur gelöscht, wenn für die unter „inactive“
angegebene Zeit nicht darauf zugegriffen wurde. Wenn auf abgelaufene Inhalte zugegriffen wird, aktualisiert NGINX sie vom Ursprungsserver und setzt den Inaktivitätstimer
zurück.use_temp_path=off
weist NGINX an, sie in dieselben Verzeichnisse zu schreiben, in denen sie zwischengespeichert werden. Wir empfehlen, diesen Parameter auf „Aus“
zu setzen, um unnötiges Kopieren von Daten zwischen Dateisystemen zu vermeiden. use_temp_path
wurde in NGINX Version 1.7.10 und NGINX Plus R6 eingeführt.Und schließlich aktiviert die Direktive proxy_cache
das Caching aller Inhalte, die mit der URL des übergeordneten Standortblocks
übereinstimmen (im Beispiel / ). Sie können die Direktive „proxy_cache“
auch in einen Serverblock
aufnehmen. Sie gilt für alle Standortblöcke
des Servers, die keine eigene Direktive „proxy_cache“
haben.
Eine leistungsstarke Funktion des NGINX- Inhaltscache besteht darin, dass NGINX so konfiguriert werden kann, dass veraltete Inhalte aus seinem Cache bereitgestellt werden, wenn keine neuen Inhalte von den Ursprungsservern abgerufen werden können. Dies kann passieren, wenn alle Ursprungsserver für eine zwischengespeicherte Ressource ausgefallen oder vorübergehend ausgelastet sind. Anstatt den Fehler an den Client weiterzuleiten, liefert NGINX die veraltete Version der Datei aus seinem Cache. Dies bietet eine zusätzliche Ebene der Fehlertoleranz für die Server, die von NGINX als Proxy verwendet werden, und stellt die Betriebszeit bei Serverausfällen oder Verkehrsspitzen sicher. Um diese Funktionalität zu aktivieren, schließen Sie die Direktive proxy_cache_use_stale
ein:
Standort / { # ... proxy_cache_use_stale Fehler Timeout http_500 http_502 http_503 http_504; }
Wenn NGINX bei dieser Beispielkonfiguration einen Fehler
, eine Zeitüberschreitung
oder einen der angegebenen 5xx-
Fehler vom Ursprungsserver empfängt und eine veraltete Version der angeforderten Datei in seinem Cache hat, liefert es die veraltete Datei, anstatt den Fehler an den Client weiterzuleiten.
NGINX verfügt über zahlreiche optionale Einstellungen zur Feinabstimmung der Cache-Leistung. Hier ist ein Beispiel, das einige davon aktiviert:
proxy_cache_path /Pfad/zum/Cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { # ... location / { proxy_cache my_cache; proxy_cache_revalidate on; proxy_cache_min_uses 3; proxy_cache_use_stale Fehler Timeout Aktualisierung http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; proxy_pass http://my_upstream; } }
Diese Anweisungen konfigurieren das folgende Verhalten:
proxy_cache_revalidate
weist NGINX an, beim Aktualisieren von Inhalten von den Ursprungsservern bedingte GET-
Anfragen zu verwenden. Wenn ein Client ein Element anfordert, das zwischengespeichert, aber gemäß der Cache-Steuerungsheader abgelaufen ist, schließt NGINX das Feld „If-Modified-Since“
in den Header der GET
-Anforderung ein, die es an den Ursprungsserver sendet. Dadurch wird Bandbreite gespart, da der Server das vollständige Element nur dann sendet, wenn es seit dem im Last-Modified
-Header aufgezeichneten Zeitpunkt geändert wurde, der an die Datei angehängt war, als NGINX es ursprünglich zwischengespeichert hat.proxy_cache_min_uses
legt fest, wie oft ein Element von Clients angefordert werden muss, bevor NGINX es zwischenspeichert. Dies ist nützlich, wenn der Cache ständig voll wird, da dadurch sichergestellt wird, dass nur die am häufigsten aufgerufenen Elemente zum Cache hinzugefügt werden. Standardmäßig ist proxy_cache_min_uses
auf 1 eingestellt.Aktualisierungsparameter
der Direktive „proxy_cache_use_stale“
weist NGINX in Kombination mit der Aktivierung der Direktive „proxy_cache_background_update“
an, veraltete Inhalte bereitzustellen, wenn Clients ein Element anfordern, das abgelaufen ist oder gerade vom Ursprungsserver aktualisiert wird. Alle Updates werden im Hintergrund durchgeführt. Die veraltete Datei wird für alle Anforderungen zurückgegeben, bis die aktualisierte Datei vollständig heruntergeladen ist.proxy_cache_lock
aktiviert ist und mehrere Clients eine Datei anfordern, die nicht aktuell im Cache ist (ein MISS
), wird nur die erste dieser Anfragen an den Ursprungsserver durchgelassen. Die verbleibenden Anforderungen warten auf die Erfüllung dieser Anforderung und ziehen dann die Datei aus dem Cache. Wenn proxy_cache_lock
nicht aktiviert ist, gehen alle Anfragen, die zu Cachefehlern führen, direkt an den Ursprungsserver.Wenn Sie über mehrere Festplatten verfügen, kann der Cache mit NGINX auf diese aufgeteilt werden. Nachfolgend sehen Sie ein Beispiel, bei dem die Clients basierend auf der Anforderungs-URI gleichmäßig auf zwei Festplatten aufgeteilt werden:
proxy_cache_path /Pfad/zu/hdd1 levels=1:2 keys_zone=my_cache_hdd1:10m max_size=10g inaktiv=60m use_temp_path=aus;
proxy_cache_path /Pfad/zu/hdd2 levels=1:2 keys_zone=my_cache_hdd2:10m
max_size=10g inaktiv=60m use_temp_path=aus;
split_clients $request_uri $my_cache {
50% „my_cache_hdd1“;
50% „my_cache_hdd2“;
}
server {
# ...
location / {
proxy_cache $my_cache;
proxy_pass http://my_upstream;
}
}
Die beiden proxy_cache_path-
Direktiven definieren zwei Caches ( my_cache_hdd1
und my_cache_hdd2
) auf zwei verschiedenen Festplatten. Der Konfigurationsblock split_clients
gibt an, dass die Ergebnisse der Hälfte der Anfragen ( 50 %
) in my_cache_hdd1
und die andere Hälfte in my_cache_hdd2
zwischengespeichert werden. Der auf der Variable $request_uri
(der Anforderungs-URI) basierende Hash bestimmt, welcher Cache für jede Anforderung verwendet wird. Dies führt dazu, dass Anforderungen für eine bestimmte URI immer im selben Cache zwischengespeichert werden.
Bitte beachten Sie, dass dieser Ansatz kein Ersatz für eine RAID-Festplattenkonfiguration ist. Bei einem Festplattenfehler kann es zu unvorhersehbarem Systemverhalten kommen. Beispielsweise kann es passieren, dass den Benutzern 500 Antwortcodes für Anfragen angezeigt werden, die an die ausgefallene Festplatte gerichtet waren. Eine ordnungsgemäße RAID-Festplattenkonfiguration kann Festplattenausfälle bewältigen.
Dieser Abschnitt beantwortet einige häufig gestellte Fragen zum NGINX-Inhaltscache.
Ja, mit der Direktive add_header
:
add_header X-Cache-Status $upstream_cache_status;
Dieses Beispiel fügt in Antworten an Clients einen X-Cache-Status
-HTTP-Header hinzu. Die folgenden Werte sind für $upstream_cache_status
möglich:
MISS
– Die Antwort wurde nicht im Cache gefunden und daher von einem Ursprungsserver abgerufen. Die Antwort wurde dann möglicherweise zwischengespeichert.BYPASS
– Die Antwort wurde vom Ursprungsserver abgerufen, anstatt aus dem Cache bereitgestellt zu werden, da die Anforderung einer Proxy_Cache_Bypass-
Direktive entsprach (siehe „Kann ich ein Loch in meinen Cache schlagen?“ weiter unten). Die Antwort wurde dann möglicherweise zwischengespeichert.ABGELAUFEN
– Der Eintrag im Cache ist abgelaufen. Die Antwort enthält aktuelle Inhalte vom Ursprungsserver.STALE
– Der Inhalt ist veraltet, weil der Ursprungsserver nicht richtig antwortet und proxy_cache_use_stale
konfiguriert wurde.AKTUALISIERUNG
– Der Inhalt ist veraltet, da der Eintrag derzeit als Antwort auf eine vorherige Anforderung aktualisiert wird und die Aktualisierung proxy_cache_use_stale
konfiguriert ist.NEU VALIDIERT
– Die Direktive proxy_cache_revalidate
wurde aktiviert und NGINX hat überprüft, ob der aktuell zwischengespeicherte Inhalt noch gültig ist ( If-Modified-Since
oder If-None-Match
).HIT
– Die Antwort enthält gültigen, aktuellen Inhalt direkt aus dem Cache.NGINX speichert eine Antwort nur dann im Cache, wenn der Ursprungsserver entweder den Expires
-Header mit einem Datum und einer Uhrzeit in der Zukunft oder den Cache-Control-
Header mit der Max-Age
-Direktive auf einen Wert ungleich Null enthält.
Standardmäßig beachtet NGINX andere Anweisungen im Cache-Control
-Header: Es speichert keine Antworten im Cache, wenn der Header die Anweisung „Private“
, „No-Cache“
oder „No-Store“
enthält. Außerdem werden Antworten mit dem Set-Cookie
-Header nicht zwischengespeichert. Außerdem werden nur Antworten auf GET-
und HEAD
-Anfragen zwischengespeichert. Sie können diese Standardeinstellungen wie in den Antworten unten beschrieben überschreiben.
NGINX speichert keine Antworten im Cache, wenn „proxy_buffering“
auf „off“
gesetzt ist. Es ist standardmäßig aktiviert
.
Cache-Control-
Header ignoriert werden?Ja, mit der Direktive proxy_ignore_headers
. Zum Beispiel mit dieser Konfiguration:
Standort /Bilder/ { Proxy-Cache mein_Cache; Proxy-Ignore-Header Cache-Steuerung; Proxy-Cache_gültig alle 30 m; # ... }
NGINX ignoriert den Cache-Control-
Header für alles unter /images/ . Die Direktive proxy_cache_valid
erzwingt ein Ablaufdatum für die zwischengespeicherten Daten und ist erforderlich, wenn Cache-Control
-Header ignoriert werden. NGINX speichert keine Dateien im Cache, die kein Ablaufdatum haben.
Set-Cookie
im Header zwischenspeichern?Ja, mit der Direktive proxy_ignore_headers
, wie in der vorherigen Antwort beschrieben.
POST-
Anfragen zwischenspeichern?Ja, mit der Direktive proxy_cache_methods
:
Proxy_Cache_Methoden: Kopf-Beitrag abrufen;
Dieses Beispiel aktiviert die Zwischenspeicherung von POST-
Anfragen.
Ja, sofern der Cache-Control-
Header dies zulässt. Das Zwischenspeichern dynamischer Inhalte, selbst für einen kurzen Zeitraum, kann die Belastung der Ursprungsserver und Datenbanken verringern und dadurch die Zeit bis zum ersten Byte verbessern, da die Seite nicht für jede Anforderung neu generiert werden muss.
Ja, mit der Direktive proxy_cache_bypass
:
Standort / { Proxy-Cache-Bypass $cookie_nocache $arg_nocache; # … }
Die Direktive definiert Anfragetypen, bei denen NGINX Inhalte sofort vom Ursprungsserver anfordert, statt zunächst zu versuchen, diese im Cache zu finden. Dies wird manchmal als „ein Loch in den Cache schlagen“ bezeichnet. In diesem Beispiel macht NGINX dies für Anfragen mit einem Nocache
-Cookie oder -Argument, zum Beispiel http://www.example.com/?nocache=true
. NGINX kann die resultierende Antwort weiterhin für zukünftige Anfragen zwischenspeichern, die nicht umgangen werden.
Die Standardform der von NGINX generierten Schlüssel ähnelt einem MD5-Hash der folgenden NGINX-Variablen : $scheme$proxy_host$request_uri
; der tatsächlich verwendete Algorithmus ist etwas komplizierter.
proxy_cache_path /Pfad/zum/Cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
Server {
# ...
Standort / {
proxy_cache my_cache;
proxy_pass http://my_upstream;
}
}
Für diese Beispielkonfiguration wird der Cache-Schlüssel für http://www.example.org/my_image.jpg
als md5(„http://my_upstream:80/my_image.jpg“)
berechnet.
Beachten Sie, dass im Hashwert die Variable $proxy_host
anstelle des tatsächlichen Hostnamens ( www.example.com
) verwendet wird. $proxy_host
wird als Name und Port des Proxyservers definiert, wie in der Direktive proxy_pass
angegeben.
Um die Variablen (oder andere Begriffe) zu ändern, die als Grundlage für den Schlüssel verwendet werden, verwenden Sie die Direktive proxy_cache_key
(siehe auch folgende Frage).
Ja, der Cache-Schlüssel kann auf einen beliebigen Wert konfiguriert werden, zum Beispiel:
Proxy -Cache-Schlüssel $Proxy-Host$Request-URI$Cookie-Jessionid;
Dieses Beispiel integriert den Wert des JSESSIONID-
Cookies in den Cache-Schlüssel. Elemente mit derselben URI, aber unterschiedlichen JSESSIONID-
Werten werden separat als eindeutige Elemente zwischengespeichert.
ETag-
Header?In NGINX 1.7.3 und NGINX Plus R5 und höher wird der ETag-
Header zusammen mit If-None-Match
vollständig unterstützt.
Wenn die Datei im Cache auf dem neuesten Stand ist, berücksichtigt NGINX eine Bytebereichsanforderung und stellt dem Client nur die angegebenen Bytes des Elements zur Verfügung. Wenn die Datei nicht zwischengespeichert ist oder veraltet ist, lädt NGINX die gesamte Datei vom Ursprungsserver herunter. Wenn die Anforderung einen einzelnen Bytebereich betrifft, sendet NGINX diesen Bereich an den Client, sobald er im Download-Stream gefunden wird. Wenn die Anforderung mehrere Bytebereiche innerhalb derselben Datei angibt, liefert NGINX dem Client die gesamte Datei, wenn der Download abgeschlossen ist.
Sobald der Download abgeschlossen ist, verschiebt NGINX die gesamte Ressource in den Cache, sodass alle zukünftigen Bytebereichsanforderungen, unabhängig davon, ob es sich um einen einzelnen oder mehrere Bereiche handelt, sofort aus dem Cache erfüllt werden.
Bitte beachten Sie, dass der Upstream-
Server Byte-Bereichsanforderungen für NGINX unterstützen muss, um Byte-Bereichsanforderungen an diesen Upstream
-Server berücksichtigen zu können.
NGINX Plus unterstützt das selektive Löschen zwischengespeicherter Dateien. Dies ist nützlich, wenn eine Datei auf dem Ursprungsserver aktualisiert wurde, aber im NGINX Plus-Cache noch gültig ist ( Cache-Control:max-age
ist noch gültig und das durch den inaktiven
Parameter der Direktive proxy_cache_path
festgelegte Timeout ist nicht abgelaufen). Mit der Cache-Purge-Funktion von NGINX Plus kann diese Datei einfach gelöscht werden. Weitere Einzelheiten finden Sie unter Löschen von Inhalten aus dem Cache .
Pragma-
Header?Der Header Pragma:no-cache
wird von Clients hinzugefügt, um alle Zwischen-Caches zu umgehen und für den angeforderten Inhalt direkt zum Ursprungsserver zu gelangen. NGINX berücksichtigt den Pragma
-Header standardmäßig nicht, aber Sie können die Funktion mit der folgenden Proxy_cache_bypass-
Direktive konfigurieren:
Standort /Bilder/ { Proxy-Cache mein_Cache; Proxy-Cache-Bypass $http_pragma; # ... }
„Stale-While-Revalidate“
und „Stale-If-Error“
für den Cache-Control-
Header?Ja, in NGINX Plus R12 und NGINX 1.11.10 und höher. Was diese Erweiterungen bewirken:
Stale-While-Revalidate-
Erweiterung des Cache-Control
-HTTP-Headers ermöglicht die Verwendung einer veralteten zwischengespeicherten Antwort, wenn diese gerade aktualisiert wird.Stale-if-Error-
Erweiterung des Cache-Control
-HTTP-Headers ermöglicht im Fehlerfall die Verwendung einer veralteten zwischengespeicherten Antwort.Diese Header haben eine niedrigere Priorität als die oben beschriebene Direktive „proxy_cache_use_stale“
.
Vary-
Header?Ja, in NGINX Plus R5 und NGINX 1.7.7 und höher. Hier ist eine gute Übersicht über den Vary
-Header .
Es gibt noch viele weitere Möglichkeiten zum Anpassen und Optimieren des NGINX-Caching. Um noch mehr über das Caching mit NGINX zu erfahren, sehen Sie sich bitte die folgenden Ressourcen an:
„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."