fastcgi_cache în Nginx

Performanță și PHP Toate versiunile Nginx

Salvează în cache răspunsurile HTML generate de PHP-FPM, servind paginile direct din Nginx fără a mai apela PHP și baza de date.

Sintaxă
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=nume:100m inactive=60m;
fastcgi_cache nume;
fastcgi_cache_valid 200 60m;

Ce face fastcgi_cache

Cu fastcgi_cache, Nginx memorează pe disc (sau în RAM, pe /dev/shm / tmpfs) pagina HTML completă generată de PHP-FPM la prima vizită și o servește direct la următoarele cereri, fără a mai porni PHP sau MySQL. Pentru un site WordPress sau de știri, diferența este uriașă: de la câteva zeci de cereri pe secundă la câteva mii de cereri pe secundă pe același server.

Configurarea are trei părți: 1) în blocul http se declară directorul și zona de chei cu fastcgi_cache_path; 2) în server se stabilesc condițiile în care cache-ul trebuie ocolit (cereri POST, utilizatori autentificați cu cookie de sesiune, coș de cumpărături); 3) în location ~ \.php$ se activează zona cu fastcgi_cache și durata cu fastcgi_cache_valid.

Adăugarea antetului add_header X-Cache-Status $upstream_cache_status; este foarte utilă pentru verificare: îți arată în răspuns dacă pagina a venit din cache (HIT), a fost generată acum (MISS), a fost ocolită intenționat (BYPASS) sau a expirat (EXPIRED).

Opțiuni și argumente

Opțiune / Parametru Descriere
fastcgi_cache_path Definește în http directorul, structura pe subdirectoare (levels=1:2), zona de chei din RAM (keys_zone), timpul după care intrările neaccesate sunt șterse (inactive) și dimensiunea maximă pe disc (max_size).
fastcgi_cache_key Cheia unică a fiecărei pagini din cache, de exemplu "$scheme$request_method$host$request_uri".
fastcgi_cache_valid Cât timp este păstrat răspunsul pentru anumite coduri HTTP (de exemplu fastcgi_cache_valid 200 301 302 60m;).
fastcgi_cache_bypass Dacă una dintre variabilele date nu este goală și nu este "0", cererea nu este luată din cache, ci merge la PHP.
fastcgi_no_cache Dacă una dintre variabile nu este goală și nu este "0", răspunsul generat de PHP nu este salvat în cache.
$upstream_cache_status Variabilă cu starea cache-ului pentru cererea curentă: MISS, HIT, BYPASS, EXPIRED, STALE.

Exemple

Exemplul 1: FastCGI cache pentru WordPress (cu excluderea utilizatorilor logați)

Vizitatorii anonimi primesc paginile din cache, iar administratorii logați văd mereu conținutul live:

# În contextul http:
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=WPCACHE:100m inactive=60m max_size=1g use_temp_path=off;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

# În contextul server:
set $skip_cache 0;

if ($request_method = POST) {
    set $skip_cache 1;
}
if ($query_string != "") {
    set $skip_cache 1;
}
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|sitemap(_index)?.xml") {
    set $skip_cache 1;
}
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $skip_cache 1;
}

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;

    fastcgi_cache        WPCACHE;
    fastcgi_cache_valid  200 301 302 60m;
    fastcgi_cache_valid  404 1m;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache     $skip_cache;
    fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
    fastcgi_cache_lock   on;

    add_header X-Cache-Status $upstream_cache_status always;
}

Exemplul 2: Verificarea antetului X-Cache-Status (MISS la prima cerere, HIT la a doua)

Două cereri consecutive către aceeași pagină:

curl -I https://example.com/
curl -I https://example.com/

Rezultat

HTTP/2 200 
server: nginx
x-cache-status: MISS

HTTP/2 200 
server: nginx
x-cache-status: HIT

Greșeli frecvente

  • Activarea fastcgi_cache fără excluderea cookie-urilor de sesiune (fastcgi_no_cache / fastcgi_cache_bypass): prima pagină încărcată de un utilizator autentificat poate fi salvată în cache și servită apoi altor vizitatori!
  • Dacă aplicația PHP trimite Cache-Control: no-cache, private (de exemplu când apelează session_start() pe toate paginile), Nginx respectă acel antet și nu salvează nimic în cache ($upstream_cache_status rămâne MISS la fiecare cerere).

Comenzi înrudite

  • fastcgi_pass: Trimite scripturile .php către PHP-FPM prin protocolul FastCGI (socket Unix sau port TCP).
  • expires: Setează antetele Cache-Control și Expires pentru ca browserul și CDN-ul să păstreze în cache fișierele statice.
  • add_header: Adaugă antete HTTP în răspunsul trimis clientului (antete de securitate HSTS, CSP, X-Frame-Options sau CORS).