srcache: Transparente, subanfragebasierte Caching-Layout für beliebige NGINX-Standorte
Installation
Sie können dieses Modul in jeder RHEL-basierten Distribution installieren, einschließlich, aber nicht beschränkt auf:
- RedHat Enterprise Linux 7, 8, 9 und 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 und Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-srcache
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-srcache
Aktivieren Sie das Modul, indem Sie Folgendes an den Anfang von /etc/nginx/nginx.conf hinzufügen:
load_module modules/ngx_http_srcache_filter_module.so;
Dieses Dokument beschreibt nginx-module-srcache v0.32 veröffentlicht am 28. Juni 2022.
upstream my_memcached {
server 10.62.136.7:11211;
keepalive 10;
}
location = /memc {
internal;
memc_connect_timeout 100ms;
memc_send_timeout 100ms;
memc_read_timeout 100ms;
memc_ignore_client_abort on;
set $memc_key $query_string;
set $memc_exptime 300;
memc_pass my_memcached;
}
location /foo {
set $key $uri$args;
srcache_fetch GET /memc $key;
srcache_store PUT /memc $key;
srcache_store_statuses 200 301 302 307 308;
# proxy_pass/fastcgi_pass/drizzle_pass/echo/etc...
# oder sogar statische Dateien auf der Festplatte
}
location = /memc2 {
internal;
memc_connect_timeout 100ms;
memc_send_timeout 100ms;
memc_read_timeout 100ms;
memc_ignore_client_abort on;
set_unescape_uri $memc_key $arg_key;
set $memc_exptime $arg_exptime;
memc_pass unix:/tmp/memcached.sock;
}
location /bar {
set_escape_uri $key $uri$args;
srcache_fetch GET /memc2 key=$key;
srcache_store PUT /memc2 key=$key&exptime=$srcache_expire;
# proxy_pass/fastcgi_pass/drizzle_pass/echo/etc...
# oder sogar statische Dateien auf der Festplatte
}
map $request_method $skip_fetch {
default 0;
POST 1;
PUT 1;
}
server {
listen 8080;
location /api/ {
set $key "$uri?$args";
srcache_fetch GET /memc $key;
srcache_store PUT /memc $key;
srcache_methods GET PUT POST;
srcache_fetch_skip $skip_fetch;
# proxy_pass/drizzle_pass/content_by_lua/echo/...
}
}
Beschreibung
Dieses Modul bietet eine transparente Caching-Schicht für beliebige NGINX-Standorte (wie solche, die ein Upstream verwenden oder sogar statische Festplattendateien bereitstellen). Das Caching-Verhalten ist größtenteils kompatibel mit RFC 2616.
In der Regel wird das memc-nginx-module zusammen mit diesem Modul verwendet, um ein konkretes Caching-Speicher-Backend bereitzustellen. Technisch gesehen können jedoch alle Module, die eine REST-Schnittstelle bereitstellen, als die von diesem Modul verwendeten Abruf- und Speicher-Subanfragen verwendet werden.
Für Hauptanfragen funktioniert die srcache_fetch Direktive am Ende der Zugriffsphase, sodass die standard access module's allow und deny Direktiven vor unseren ausgeführt werden, was aus Sicherheitsgründen normalerweise das gewünschte Verhalten ist.
Der Workflow dieses Moduls sieht wie folgt aus:

Subanfrage-Caching
Für Subanfragen verbieten wir ausdrücklich die Verwendung dieses Moduls, da es zu schwierig ist, es richtig zu machen. Es gab früher eine Implementierung, aber sie war fehlerhaft und ich habe schließlich aufgegeben, sie zu reparieren und sie aufgegeben.
Wenn Sie jedoch das lua-nginx-module verwenden, ist es einfach, das Subanfrage-Caching in Lua selbst zu machen. Das heißt, zuerst eine Subanfrage an einen memc-nginx-module Standort ausführen, um eine explizite Cache-Abfrage durchzuführen. Wenn der Cache-Hit erfolgt, verwenden Sie einfach die zurückgegebenen Cachedaten; andernfalls fallen Sie auf das echte Backend zurück und führen schließlich eine Cache-Einfügung durch, um die Daten in den Cache zu speisen.
Die Verwendung dieses Moduls für das Hauptanfrage-Caching und Lua für das Subanfrage-Caching ist der Ansatz, den wir in unserem Geschäft verfolgen. Diese hybride Lösung funktioniert großartig in der Produktion.
Verteiltes Memcached-Caching
Hier ist ein einfaches Beispiel, das einen verteilten Memcached-Caching-Mechanismus demonstriert, der auf diesem Modul basiert. Angenommen, wir haben drei verschiedene Memcached-Knoten und verwenden einfaches Modulo, um unsere Schlüssel zu hashen.
http {
upstream moon {
server 10.62.136.54:11211;
server unix:/tmp/memcached.sock backup;
}
upstream earth {
server 10.62.136.55:11211;
}
upstream sun {
server 10.62.136.56:11211;
}
upstream_list universe moon earth sun;
server {
memc_connect_timeout 100ms;
memc_send_timeout 100ms;
memc_read_timeout 100ms;
location = /memc {
internal;
set $memc_key $query_string;
set_hashed_upstream $backend universe $memc_key;
set $memc_exptime 3600; # in Sekunden
memc_pass $backend;
}
location / {
set $key $uri;
srcache_fetch GET /memc $key;
srcache_store PUT /memc $key;
# proxy_pass/fastcgi_pass/content_by_lua/drizzle_pass/...
}
}
}
moon, earth und sun. Dies sind unsere drei Memcached-Server.
2. Dann gruppieren wir sie als ein Upstream-Listen-Element mit der upstream_list Direktive, die von set-misc-nginx-module bereitgestellt wird.
3. Danach definieren wir einen internen Standort namens /memc, um mit dem Memcached-Cluster zu kommunizieren.
4. In diesem /memc Standort setzen wir zuerst die $memc_key Variable mit der Abfragezeichenfolge ($args) und verwenden dann die set_hashed_upstream Direktive, um unseren $memc_key über die Upstream-Liste universe zu hashen, um einen konkreten Upstream-Namen zu erhalten, der der Variable $backend zugewiesen wird.
5. Wir übergeben diese $backend Variable an die memc_pass Direktive. Die $backend Variable kann einen Wert unter moon, earth und sun halten.
6. Außerdem definieren wir die Memcached-Caching-Ablaufzeit auf 3600 Sekunden (d.h. eine Stunde), indem wir die $memc_exptime Variable überschreiben.
7. In unserem Hauptöffentlichen Standort / konfigurieren wir die $uri Variable als unseren Cache-Schlüssel und konfigurieren dann srcache_fetch für Cache-Abfragen und srcache_store für Cache-Aktualisierungen. Wir verwenden zwei Subanfragen an unseren zuvor definierten /memc Standort in diesen beiden Direktiven.
Man kann die set_by_lua oder rewrite_by_lua Direktiven des lua-nginx-module verwenden, um benutzerdefinierten Lua-Code einzufügen, um die $backend und/oder $key Variablen im obigen Beispiel zu berechnen.
Eine Sache, die beachtet werden sollte, ist, dass Memcached Einschränkungen bei der Schlüssellänge hat, d.h. 250 Bytes, sodass für Schlüssel, die sehr lang sein könnten, man die set_md5 Direktive oder deren Freunde verwenden kann, um den Schlüssel vor der Zuweisung an $memc_key im /memc Standort oder ähnlichem auf einen festen Längen-Hash zu hashen.
Darüber hinaus kann man die srcache_fetch_skip und srcache_store_skip Direktiven nutzen, um zu steuern, was pro Anfrage gecached werden soll und was nicht, und Lua kann hier auf ähnliche Weise verwendet werden. Die Möglichkeiten sind also wirklich unbegrenzt.
Um die Geschwindigkeit zu maximieren, aktivieren wir oft den TCP (oder Unix Domain Socket) Verbindungs-Pool für unsere Memcached-Upstreams, bereitgestellt durch HttpUpstreamKeepaliveModule, zum Beispiel,
upstream moon {
server 10.62.136.54:11211;
server unix:/tmp/memcached.sock backup;
keepalive 10;
}
wobei wir einen Verbindungs-Pool definieren, der bis zu 10 Keep-Alive-Verbindungen (pro NGINX-Worker-Prozess) für unseren moon Upstream (Cluster) hält.
Caching mit Redis
Redis ist ein alternatives Schlüssel-Wert-Speicher mit vielen zusätzlichen Funktionen.
Hier ist ein funktionierendes Beispiel mit dem lua-resty-redis Modul:
location ~ '\.php$|^/update.php' {
# Cache-Einrichtung
set $key $request_uri;
try_files $uri =404;
srcache_fetch_skip $skip_cache;
srcache_store_skip $skip_cache;
srcache_response_cache_control off;
srcache_store_statuses 200 201 301 302 307 308 404 503;
set_escape_uri $escaped_key $key;
srcache_fetch GET /redis-fetch $key;
srcache_store PUT /redis-store key=$escaped_key;
more_set_headers 'X-Cache-Fetch-Status $srcache_fetch_status';
more_set_headers 'X-Cache-Store-Status $srcache_store_status';
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
# Sicherheitsnotiz: Wenn Sie eine PHP-Version verwenden, die älter ist als die
# neueste 5.3, sollten Sie "cgi.fix_pathinfo = 0;" in php.ini haben.
# Siehe http://serverfault.com/q/627903/94922 für Details.
include fastcgi_params;
# Blockiere httproxy-Angriffe. Siehe https://httpoxy.org/.
fastcgi_param HTTP_PROXY "";
fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_intercept_errors on;
fastcgi_pass upstream-name;
}
location /redis-fetch {
internal;
resolver 8.8.8.8 valid=300s;
resolver_timeout 10s;
content_by_lua_block {
local key = assert(ngx.var.request_uri, "kein Schlüssel gefunden")
local redis = require "resty.redis"
local red, err = redis:new()
if not red then
ngx.log(ngx.ERR, "Fehler beim Erstellen der Redis-Variable, Fehler -> ", err)
ngx.exit(500)
end
assert(red:connect("redis-master.default.svc.cluster.local", 6379))
if not red then
ngx.log(ngx.ERR, "Fehler beim Verbinden mit Redis, Fehler -> ", err)
ngx.exit(500)
end
local res, err = red:auth("redispassword")
if not res then
ngx.say("Fehler bei der Authentifizierung, ", err)
ngx.exit(500)
end
local data = assert(red:get(key))
assert(red:set_keepalive(10000, 100))
if res == ngx.null then
return ngx.exit(404)
end
ngx.print(data)
}
}
location /redis-store {
internal;
resolver 8.8.8.8 valid=300s;
resolver_timeout 10s;
content_by_lua_block {
local value = assert(ngx.req.get_body_data(), "kein Wert gefunden")
local key = assert(ngx.var.request_uri, "kein Schlüssel gefunden")
local redis = require "resty.redis"
local red, err = redis:new()
if not red then
ngx.log(ngx.ERR, "Fehler beim Erstellen der Redis-Variable, Fehler -> ", err)
ngx.exit(500)
end
assert(red:connect("redis-master.default.svc.cluster.local", 6379))
if not red then
ngx.log(ngx.ERR, "Fehler beim Verbinden mit Redis, Fehler -> ", err)
ngx.exit(500)
end
local res, err = red:auth("redispassword")
if not res then
ngx.say("Fehler bei der Authentifizierung, ", err)
ngx.exit(500)
end
local data = assert(red:set(key, value))
assert(red:set_keepalive(10000, 100))
if res == ngx.null then
return ngx.exit(404)
end
}
}
Hier ist ein funktionierendes Beispiel mit den HTTPRedis (fetch) und Redis2 (store) Modulen:
location /api {
default_type text/css;
set $key $uri;
set_escape_uri $escaped_key $key;
srcache_fetch GET /redis $key;
srcache_store PUT /redis2 key=$escaped_key&exptime=120;
# fastcgi_pass/proxy_pass/drizzle_pass/postgres_pass/echo/etc
}
location = /redis {
internal;
set_md5 $redis_key $args;
redis_pass 127.0.0.1:6379;
}
location = /redis2 {
internal;
set_unescape_uri $exptime $arg_exptime;
set_unescape_uri $key $arg_key;
set_md5 $key;
redis2_query set $key $echo_request_body;
redis2_query expire $key $exptime;
redis2_pass 127.0.0.1:6379;
}
Dieses Beispiel verwendet die $echo_request_body Variable, die vom echo-nginx-module bereitgestellt wird. Beachten Sie, dass Sie die neueste Version des echo-nginx-module, v0.38rc2, benötigen, da frühere Versionen möglicherweise nicht zuverlässig funktionieren.
Außerdem benötigen Sie sowohl das HttpRedisModule als auch das redis2-nginx-module. Letzteres wird in der srcache_store Subanfrage verwendet.
Der Nginx-Kern hat auch einen Fehler, der verhindern könnte, dass die Pipelining-Unterstützung des redis2-nginx-module unter bestimmten extremen Bedingungen ordnungsgemäß funktioniert. Und der folgende Patch behebt dies:
http://mailman.nginx.org/pipermail/nginx-devel/2012-March/002040.html
Beachten Sie jedoch, dass, wenn Sie das OpenResty 1.0.15.3 Bundle oder später verwenden, Sie bereits alles haben, was Sie hier im Bundle benötigen.
Cache-Schlüssel-Vorverarbeitung
Es ist oft wünschenswert, den Cache-Schlüssel vorzubereiten, um zufällige Störungen auszuschließen, die die Cache-Trefferquote beeinträchtigen könnten. Zum Beispiel sollten zufällige Sitzungs-IDs in den URI-Argumenten normalerweise entfernt werden.
Betrachten Sie die folgende URI-Abfragezeichenfolge:
SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK&RT=62
wir möchten die Argumente SID und UID daraus entfernen. Es ist einfach zu erreichen, wenn Sie gleichzeitig das lua-nginx-module verwenden:
location = /t {
rewrite_by_lua '
local args = ngx.req.get_uri_args()
args.SID = nil
args.UID = nil
ngx.req.set_uri_args(args)
';
echo $args;
}
Hier verwenden wir die echo Direktive des echo-nginx-module, um den endgültigen Wert von $args am Ende auszugeben. Sie können es durch Ihre srcache-nginx-module Konfigurationen und Upstream-Konfigurationen ersetzen.
Lassen Sie uns dieses /t-Interface mit curl testen:
$ curl 'localhost:8081/t?RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK'
M=1&UNC=0&RT=62&H=1&L=EN&SRC=LK
Es ist erwähnenswert, dass, wenn Sie die Reihenfolge der URI-Argumente beibehalten möchten, Sie direkt String-Ersetzungen auf dem Wert von $args durchführen können, zum Beispiel:
location = /t {
rewrite_by_lua '
local args = ngx.var.args
newargs, n, err = ngx.re.gsub(args, [[\b[SU]ID=[^&]*&?]], "", "jo")
if n and n > 0 then
ngx.var.args = newargs
end
';
echo $args;
}
Testen Sie es jetzt erneut mit dem ursprünglichen curl-Befehl, erhalten wir genau das, was wir erwarten:
RT=62&L=EN&M=1&H=1&UNC=0&SRC=LK
Für Caching-Zwecke ist es jedoch gut, die Reihenfolge der URI-Argumente zu normalisieren, damit Sie die Cache-Trefferquote erhöhen können. Und die Reihenfolge der Hash-Tabelleneinträge, die von LuaJIT oder Lua verwendet wird, kann als schöner Nebeneffekt zur Normalisierung der Reihenfolge verwendet werden.
Direktiven
srcache_fetch
syntax: srcache_fetch <method> <uri> <args>?
default: nein
context: http, server, location, location if
phase: post-access
Diese Direktive registriert einen Handler für die Zugriffsphase, der eine NGINX-Subanfrage zur Cache-Abfrage ausführt.
Wenn die Subanfrage einen Statuscode zurückgibt, der nicht 200 ist, wird ein Cache-Miss signalisiert und der Kontrollfluss wird zu späteren Phasen fortgesetzt, einschließlich der Inhaltsphase, die von ngx_http_proxy_module, ngx_http_fastcgi_module und anderen konfiguriert wird. Wenn die Subanfrage 200 OK zurückgibt, wird ein Cache-Hit signalisiert und dieses Modul sendet die Antwort der Subanfrage direkt als Antwort der aktuellen Hauptanfrage an den Client.
Diese Direktive wird immer am Ende der Zugriffsphase ausgeführt, sodass die ngx_http_access_module's allow und deny immer vor dieser ausgeführt werden.
Sie können die srcache_fetch_skip Direktive verwenden, um die Cache-Abfrage selektiv zu deaktivieren.
srcache_fetch_skip
syntax: srcache_fetch_skip <flag>
default: srcache_fetch_skip 0
context: http, server, location, location if
phase: post-access
Das <flag> Argument unterstützt NGINX-Variablen. Wenn der Wert dieses Arguments nicht leer und nicht gleich 0 ist, wird der Abrufprozess bedingungslos übersprungen.
Zum Beispiel, um Caching-Anfragen zu überspringen, die ein Cookie namens foo mit dem Wert bar haben, können wir schreiben
location / {
set $key ...;
set_by_lua $skip '
if ngx.var.cookie_foo == "bar" then
return 1
end
return 0
';
srcache_fetch_skip $skip;
srcache_store_skip $skip;
srcache_fetch GET /memc $key;
srcache_store GET /memc $key;
# proxy_pass/fastcgi_pass/content_by_lua/...
}
$skip Variable in der (früheren) Rewrite-Phase zu berechnen. Ähnlich kann die $key Variable auch mit Lua unter Verwendung der set_by_lua oder rewrite_by_lua Direktive berechnet werden.
Die standardmäßige map Direktive kann ebenfalls verwendet werden, um den Wert der $skip Variable zu berechnen, die im obigen Beispiel verwendet wird:
map $cookie_foo $skip {
default 0;
bar 1;
}
aber Ihre map Anweisung sollte in den http Konfigurationsblock in Ihrer nginx.conf Datei eingefügt werden.
srcache_store
syntax: srcache_store <method> <uri> <args>?
default: nein
context: http, server, location, location if
phase: output-filter
Diese Direktive registriert einen Handler für den Ausgabe-Filter, der eine NGINX-Subanfrage ausführt, um die Antwort der aktuellen Hauptanfrage in ein Cache-Backend zu speichern. Der Statuscode der Subanfrage wird ignoriert.
Sie können die srcache_store_skip und srcache_store_max_size Direktiven verwenden, um das Caching für bestimmte Anfragen im Falle eines Cache-Misses zu deaktivieren.
Seit der Veröffentlichung von v0.12rc7 werden sowohl die Antwort-Statuszeile, die Antwort-Header als auch die Antwortkörper in den Cache gelegt. Standardmäßig werden die folgenden speziellen Antwort-Header nicht zwischengespeichert:
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailers
- Transfer-Encoding
- Upgrade
- Set-Cookie
Sie können die srcache_store_pass_header und/oder srcache_store_hide_header Direktiven verwenden, um zu steuern, welche Header gespeichert werden sollen und welche nicht.
Die ursprünglichen Antwortdaten werden sofort gesendet, sobald sie ankommen. srcache_store kopiert und sammelt die Daten einfach in einem Ausgabe-Filter, ohne sie vom Senden an den downstream zu verzögern.
Bitte beachten Sie jedoch, dass, obwohl alle Antwortdaten sofort gesendet werden, die aktuelle NGINX-Anforderungslebensdauer nicht endet, bis die srcache_store Subanfrage abgeschlossen ist. Das bedeutet eine Verzögerung beim Schließen der TCP-Verbindung auf der Serverseite (wenn HTTP Keepalive deaktiviert ist, sollten jedoch ordnungsgemäße HTTP-Clients die Verbindung aktiv auf der Clientseite schließen, was keine zusätzliche Verzögerung oder andere Probleme verursacht) oder beim Bedienen der nächsten Anfrage, die über dieselbe TCP-Verbindung gesendet wird (wenn HTTP Keepalive aktiv ist).
srcache_store_max_size
syntax: srcache_store_max_size <size>
default: srcache_store_max_size 0
context: http, server, location, location if
phase: output-header-filter
Wenn die Länge des Antwortkörpers diese Größe überschreitet, wird dieses Modul nicht versuchen, den Antwortkörper mit der in srcache_store angegebenen Subanfrage-Vorlage im Cache zu speichern.
Dies ist besonders nützlich, wenn ein Cache-Speicher-Backend verwendet wird, das eine harte obere Grenze für die Eingabedaten hat. Zum Beispiel hat der Memcached-Server eine Standardgrenze von 1 MB pro Element.
Wenn 0 angegeben wird (der Standardwert), gibt es keine Grenzprüfung.
srcache_store_skip
syntax: srcache_store_skip <flag>
default: srcache_store_skip 0
context: http, server, location, location if
phase: output-header-filter
Das <flag> Argument unterstützt NGINX-Variablen. Wenn der Wert dieses Arguments nicht leer und nicht gleich 0 ist, wird der Speicherprozess bedingungslos übersprungen.
Seit der Veröffentlichung von v0.25 kann der <flag> Ausdruck (möglicherweise mit NGINX-Variablen) bis zu zweimal ausgewertet werden: das erste Mal direkt nach dem Senden des Antwort-Headers und wenn der <flag> Ausdruck nicht als wahr ausgewertet wird, wird er erneut ausgewertet, sobald das Ende des Antwortkörperdatenstroms erreicht ist. Vor v0.25 wurde nur die erste Auswertung durchgeführt.
Hier ist ein Beispiel, das Lua verwendet, um $nocache zu setzen, um das Speichern von URIs zu vermeiden, die den String "/tmp" enthalten:
set_by_lua $nocache '
if string.match(ngx.var.uri, "/tmp") then
return 1
end
return 0';
srcache_store_skip $nocache;
srcache_store_statuses
syntax: srcache_store_statuses <status1> <status2> ..
default: srcache_store_statuses 200 301 302 307 308
context: http, server, location, location if
phase: output-header-filter
Diese Direktive steuert, welche Antworten gemäß ihrem Statuscode im Cache gespeichert werden.
Standardmäßig werden nur 200, 301, 302, 307 und 308 Antworten im Cache gespeichert, und alle anderen Antworten überspringen srcache_store.
Sie können beliebige positive Zahlen für den Antwortstatuscode angeben, den Sie zwischenspeichern möchten, einschließlich Fehlercodes wie 404 und 503. Zum Beispiel:
srcache_store_statuses 200 201 301 302 307 308 404 503;
Mindestens ein Argument sollte dieser Direktive gegeben werden.
Diese Direktive wurde erstmals in der Veröffentlichung v0.13rc2 eingeführt.
srcache_store_ranges
syntax: srcache_store_ranges on|off
default: srcache_store_ranges off
context: http, server, location, location if
phase: output-body-filter
Wenn diese Direktive aktiviert ist (standardmäßig auf off), wird srcache_store auch 206 Partial Content-Antworten speichern, die vom standardmäßigen ngx_http_range_filter_module generiert werden. Wenn Sie diese Direktive aktivieren, müssen Sie $http_range zu Ihren Cache-Schlüsseln hinzufügen. Zum Beispiel:
location / {
set $key "$uri$args$http_range";
srcache_fetch GET /memc $key;
srcache_store PUT /memc $key;
}
Diese Direktive wurde erstmals in der Veröffentlichung v0.27 eingeführt.
srcache_header_buffer_size
syntax: srcache_header_buffer_size <size>
default: srcache_header_buffer_size 4k/8k
context: http, server, location, location if
phase: output-header-filter
Diese Direktive steuert den Header-Puffer beim Serialisieren von Antwort-Headern für srcache_store. Die Standardgröße ist die Seitengröße, normalerweise 4k oder 8k, abhängig von den spezifischen Plattformen.
Beachten Sie, dass der Puffer nicht verwendet wird, um alle Antwort-Header zu halten, sondern nur jeden einzelnen Header. Daher muss der Puffer lediglich groß genug sein, um den längsten Antwort-Header zu halten.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
srcache_store_hide_header
syntax: srcache_store_hide_header <header>
default: nein
context: http, server, location, location if
phase: output-header-filter
Standardmäßig speichert dieses Modul alle Antwort-Header, mit Ausnahme der folgenden:
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailers
- Transfer-Encoding
- Upgrade
- Set-Cookie
Sie können sogar noch mehr Antwort-Header von srcache_store ausblenden, indem Sie deren Namen (nicht großgeschrieben) mit dieser Direktive auflisten. Zum Beispiel:
srcache_store_hide_header X-Foo;
srcache_store_hide_header Last-Modified;
Mehrere Vorkommen dieser Direktive sind in einem einzelnen Standort erlaubt.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
Siehe auch srcache_store_pass_header.
srcache_store_pass_header
syntax: srcache_store_pass_header <header>
default: nein
context: http, server, location, location if
phase: output-header-filter
Standardmäßig speichert dieses Modul alle Antwort-Header, mit Ausnahme der folgenden:
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailers
- Transfer-Encoding
- Upgrade
- Set-Cookie
Sie können srcache_store zwingen, einen oder mehrere dieser Antwort-Header von srcache_store zu speichern, indem Sie deren Namen (nicht großgeschrieben) mit dieser Direktive auflisten. Zum Beispiel:
srcache_store_pass_header Set-Cookie;
srcache_store_pass_header Proxy-Authenticate;
Mehrere Vorkommen dieser Direktive sind in einem einzelnen Standort erlaubt.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
Siehe auch srcache_store_hide_header.
srcache_methods
syntax: srcache_methods <method>...
default: srcache_methods GET HEAD
context: http, server, location
phase: post-access, output-header-filter
Diese Direktive gibt die HTTP-Anforderungsmethoden an, die von entweder srcache_fetch oder srcache_store berücksichtigt werden. HTTP-Anforderungsmethoden, die nicht aufgeführt sind, werden vollständig aus dem Cache übersprungen.
Die folgenden HTTP-Methoden sind erlaubt: GET, HEAD, POST, PUT und DELETE. Die Methoden GET und HEAD sind immer implizit in der Liste enthalten, unabhängig von ihrer Präsenz in dieser Direktive.
Beachten Sie, dass seit der Veröffentlichung von v0.17 HEAD-Anfragen immer von srcache_store übersprungen werden, da ihre Antworten niemals einen Antwortkörper tragen.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
srcache_ignore_content_encoding
syntax: srcache_ignore_content_encoding on|off
default: srcache_ignore_content_encoding off
context: http, server, location, location if
phase: output-header-filter
Wenn diese Direktive auf off (was der Standard ist) eingestellt ist, führt ein nicht leerer Content-Encoding Antwort-Header dazu, dass srcache_store das gesamte Antwortdokument im Cache überspringt und eine Warnung in der NGINX error.log Datei wie folgt ausgibt:
[warn] 12500#0: *1 srcache_store übersprungen aufgrund des Antwort-Headers "Content-Encoding: gzip"
(vielleicht haben Sie vergessen, die Kompression auf dem Backend zu deaktivieren?)
Wenn Sie diese Direktive aktivieren, wird der Content-Encoding Antwort-Header ignoriert und die Antwort wie gewohnt gespeichert (und auch ohne Warnung).
Es wird empfohlen, die gzip/deflate-Kompression auf Ihrem Backend-Server immer zu deaktivieren, indem Sie die folgende Zeile in Ihrer nginx.conf Datei angeben:
proxy_set_header Accept-Encoding "";
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
srcache_request_cache_control
syntax: srcache_request_cache_control on|off
default: srcache_request_cache_control off
context: http, server, location
phase: post-access, output-header-filter
Wenn diese Direktive aktiviert ist, werden die Anfrage-Header Cache-Control und Pragma von diesem Modul in den folgenden Weisen beachtet:
- srcache_fetch, d.h. die Cache-Abfrageoperation, wird übersprungen, wenn die Anfrage-Header
Cache-Control: no-cacheund/oderPragma: no-cachevorhanden sind. - srcache_store, d.h. die Cache-Speicheroperation, wird übersprungen, wenn der Anfrage-Header
Cache-Control: no-storeangegeben ist.
Das Deaktivieren dieser Direktive schaltet diese Funktionalität aus und wird als sicherer für stark frequentierte Seiten angesehen, die hauptsächlich auf Cache für Geschwindigkeit angewiesen sind.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
Siehe auch srcache_response_cache_control.
srcache_response_cache_control
syntax: srcache_response_cache_control on|off
default: srcache_response_cache_control on
context: http, server, location
phase: output-header-filter
Wenn diese Direktive aktiviert ist, werden die Antwort-Header Cache-Control und Expires von diesem Modul in den folgenden Weisen beachtet:
Cache-Control: privateüberspringt srcache_store,Cache-Control: no-storeüberspringt srcache_store,Cache-Control: no-cacheüberspringt srcache_store,Cache-Control: max-age=0überspringt srcache_store,- und
Expires: <date-no-more-recently-than-now>überspringt srcache_store.
Diese Direktive hat Vorrang vor den Direktiven srcache_store_no_store, srcache_store_no_cache und srcache_store_private.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
Siehe auch srcache_request_cache_control.
srcache_store_no_store
syntax: srcache_store_no_store on|off
default: srcache_store_no_store off
context: http, server, location
phase: output-header-filter
Das Aktivieren dieser Direktive zwingt Antworten mit dem Header Cache-Control: no-store, im Cache gespeichert zu werden, wenn srcache_response_cache_control aktiviert ist und andere Bedingungen erfüllt sind. Standardmäßig auf off.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
srcache_store_no_cache
syntax: srcache_store_no_cache on|off
default: srcache_store_no_cache off
context: http, server, location
phase: output-header-filter
Das Aktivieren dieser Direktive zwingt Antworten mit dem Header Cache-Control: no-cache, im Cache gespeichert zu werden, wenn srcache_response_cache_control aktiviert ist und andere Bedingungen erfüllt sind. Standardmäßig auf off.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
srcache_store_private
syntax: srcache_store_private on|off
default: srcache_store_private off
context: http, server, location
phase: output-header-filter
Das Aktivieren dieser Direktive zwingt Antworten mit dem Header Cache-Control: private, im Cache gespeichert zu werden, wenn srcache_response_cache_control aktiviert ist und andere Bedingungen erfüllt sind. Standardmäßig auf off.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
srcache_default_expire
syntax: srcache_default_expire <time>
default: srcache_default_expire 60s
context: http, server, location, location if
phase: output-header-filter
Diese Direktive steuert den Standardablaufzeitraum, der für den Wert der $srcache_expire Variable zulässig ist, wenn weder Cache-Control: max-age=N noch Expires in den Antwort-Headern angegeben sind.
Die <time> Argumentwerte sind standardmäßig in Sekunden. Es ist jedoch ratsam, immer die Zeiteinheit explizit anzugeben, um Verwirrung zu vermeiden. Unterstützte Zeiteinheiten sind "s" (Sekunden), "ms" (Millisekunden), "y" (Jahre), "M" (Monate), "w" (Wochen), "d" (Tage), "h" (Stunden) und "m" (Minuten). Zum Beispiel:
srcache_default_expire 30m; # 30 Minuten
Diese Zeit muss weniger als 597 Stunden betragen.
Die Semantik einer Null-Ablaufzeit hängt vom tatsächlichen Cache-Backend-Speicher ab, den Sie derzeit verwenden, was für dieses Modul irrelevant ist. Im Fall von Memcached bedeutet beispielsweise eine Null-Ablaufzeit, dass das Element niemals abläuft.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
srcache_max_expire
syntax: srcache_max_expire <time>
default: srcache_max_expire 0
context: http, server, location, location if
phase: output-header-filter
Diese Direktive steuert den maximalen Ablaufzeitraum, der für den Wert der $srcache_expire Variable zulässig ist. Diese Einstellung hat Vorrang vor anderen Berechnungsmethoden.
Die <time> Argumentwerte sind standardmäßig in Sekunden. Es ist jedoch ratsam, immer die Zeiteinheit explizit anzugeben, um Verwirrung zu vermeiden. Unterstützte Zeiteinheiten sind "s" (Sekunden), "ms" (Millisekunden), "y" (Jahre), "M" (Monate), "w" (Wochen), "d" (Tage), "h" (Stunden) und "m" (Minuten). Zum Beispiel:
srcache_max_expire 2h; # 2 Stunden
Diese Zeit muss weniger als 597 Stunden betragen.
Wenn 0 angegeben wird, was die Standardeinstellung ist, gibt es keine Begrenzung.
Diese Direktive wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
Variablen
$srcache_expire
type: integer
cacheable: nein
writable: nein
Diese NGINX-Variable gibt die empfohlene Ablaufzeit (in Sekunden) für die aktuelle Antwort an, die im Cache gespeichert wird. Der Algorithmus zur Berechnung des Wertes ist wie folgt:
- Wenn der Antwort-Header
Cache-Control: max-age=Nangegeben ist, wirdNals Ablaufzeit verwendet, - andernfalls, wenn der Antwort-Header
Expiresangegeben ist, wird die Ablaufzeit durch Subtrahieren des aktuellen Zeitstempels von der imExpiresHeader angegebenen Zeit erhalten, - wenn weder
Cache-Control: max-age=NnochExpiresHeader angegeben sind, verwenden Sie den Wert, der in der srcache_default_expire Direktive angegeben ist.
Der endgültige Wert dieser Variablen wird der Wert sein, der durch die srcache_max_expire Direktive angegeben ist, wenn der in dem obigen Algorithmus erhaltene Wert den maximalen Wert (sofern vorhanden) überschreitet.
Sie müssen diese Variable nicht für die Ablaufzeit verwenden.
Diese Variable wurde erstmals in der Veröffentlichung v0.12rc7 eingeführt.
$srcache_fetch_status
type: string
cacheable: nein
writable: nein
Diese NGINX-Variable wird auf den Status der "Fetch"-Phase für das Caching-System ausgewertet. Drei Werte sind möglich: HIT, MISS und BYPASS.
Wenn die "Fetch"-Subanfrage einen Statuscode zurückgibt, der nicht 200 ist, oder ihre Antwortdaten nicht gut formatiert sind, wird diese Variable auf den Wert MISS ausgewertet.
Der Wert dieser Variablen ist nur nach der Zugriffsanforderungsbearbeitungsphase sinnvoll, oder BYPASS wird immer angegeben.
Diese Variable wurde erstmals in der Veröffentlichung v0.14 eingeführt.
$srcache_store_status
type: string
cacheable: nein
writable: nein
Diese NGINX-Variable gibt den aktuellen Cache-Status für die "Store"-Phase an. Zwei mögliche Werte, STORE und BYPASS, können erhalten werden.
Da die Antworten für die "Store"-Subanfrage immer verworfen werden, wird der Wert dieser Variablen immer STORE sein, solange die "Store"-Subanfrage tatsächlich ausgeführt wird.
Der Wert dieser Variablen ist nur sinnvoll, wenn die Anfrage-Header der aktuellen (Haupt-)Anfrage gesendet werden. Das endgültige Ergebnis kann nur erhalten werden, nachdem der gesamte Antwortkörper gesendet wurde, wenn der Content-Length Antwort-Header für die Hauptanfrage nicht angegeben ist.
Diese Variable wurde erstmals in der Veröffentlichung v0.14 eingeführt.
Bekannte Probleme
- In bestimmten Systemen kann das Aktivieren von aio und/oder sendfile dazu führen, dass srcache_store nicht funktioniert. Sie können sie in den Standorten deaktivieren, die von srcache_store konfiguriert sind.
- Die srcache_store Direktive kann nicht verwendet werden, um die Antworten zu erfassen, die von den Subanfrage-Direktiven von echo-nginx-module wie echo_subrequest_async und echo_location generiert werden. Es wird empfohlen, HttpLuaModule zu verwenden, um Subanfragen zu initiieren und zu erfassen, was mit srcache_store funktionieren sollte.
Vorsichtsmaßnahmen
- Es wird empfohlen, die gzip-Kompression Ihres Backend-Servers zu deaktivieren und das NGINX ngx_http_gzip_module zu verwenden, um die Arbeit zu erledigen. Im Falle des ngx_http_proxy_module können Sie die folgende Konfiguration verwenden, um die Backend-gzip-Kompression zu deaktivieren:
proxy_set_header Accept-Encoding ""; - Verwenden Sie nicht die ngx_http_rewrite_module's if Direktive im selben Standort wie diese Modul, da "if böse ist". Verwenden Sie stattdessen ngx_http_map_module oder lua-nginx-module in Kombination mit den srcache_store_skip und/oder srcache_fetch_skip Direktiven dieses Moduls. Zum Beispiel:
map $request_method $skip_fetch { default 0; POST 1; PUT 1; } server { listen 8080; location /api/ { set $key "$uri?$args"; srcache_fetch GET /memc $key; srcache_store PUT /memc $key; srcache_methods GET PUT POST; srcache_fetch_skip $skip_fetch; # proxy_pass/drizzle_pass/content_by_lua/echo/... } }
Fehlersuche
Um Probleme zu debuggen, sollten Sie immer zuerst Ihre NGINX error.log Datei überprüfen. Wenn keine Fehlermeldungen ausgegeben werden, müssen Sie die NGINX-Debug-Protokolle aktivieren, um mehr Details zu erhalten, wie in debugging log erklärt.
Einige häufige Fallstricke für Anfänger:
- Die ursprüngliche Antwort trägt einen
Cache-ControlHeader, der das Caching ausdrücklich deaktiviert, und Sie konfigurieren keine Direktiven wie srcache_response_cache_control. - Die ursprüngliche Antwort ist bereits gzip-komprimiert, was standardmäßig nicht zwischengespeichert wird (siehe srcache_ignore_content_encoding).
- Memcached könnte
CLIENT_ERROR bad command line formatzurückgeben, wenn ein zu langer Schlüssel verwendet wird (250 Zeichen ab Version 1.4.25). Es ist daher sicherer,set_md5 $key $uri$args;anstelle vonset $key $uri$args;zu verwenden. Dieset_md5Direktive (und mehr) ist im OpenResty's set-misc module verfügbar. - NGINX könnte
client intended to send too large bodyzurückgeben, wenn versucht wird, Objekte größer als 1 MB im Speicher-Backend zu speichern, in diesem Fall mussclient_max_body_sizevon nginx auf einen höheren Wert gesetzt werden. - Memcached könnte fehlschlagen, Objekte größer als 1 MB zu speichern, was zu Fehlern wie
srcache_store subrequest failed status=502führt. Seit Version 1.4.2 unterstützt Memcached eine Befehlszeilenoption-I, um die Standardgröße jeder Slab-Seite zu überschreiben. Bitte lesen Sie die Man-Seite für weitere Informationen.
Test Suite
Dieses Modul wird mit einer von Perl gesteuerten Test-Suite geliefert. Die Testfälle sind ebenfalls deklarativ. Dank des Test::Nginx Moduls in der Perl-Welt.
Um es auf Ihrer Seite auszuführen:
$ PATH=/path/to/your/nginx-with-srcache-module:$PATH prove -r t
Da ein einzelner NGINX-Server (standardmäßig localhost:1984) in allen Testskripten (.t Dateien) verwendet wird, ist es bedeutungslos, die Test-Suite parallel auszuführen, indem Sie -jN beim Aufrufen des prove-Utilities angeben.
Einige Teile der Test-Suite erfordern auch, dass die Module ngx_http_rewrite_module, echo-nginx-module, rds-json-nginx-module und drizzle-nginx-module beim Erstellen von NGINX aktiviert sind.
Siehe auch
GitHub
Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub Repository für nginx-module-srcache.