web-dev-qa-db-fra.com

Comment configurer Nginx comme proxy inverse de mise en cache?

J'ai entendu récemment que Nginx a ajouté la mise en cache à sa fonction de proxy inverse. J'ai regardé autour de moi mais je n'ai pas trouvé beaucoup d'informations à ce sujet.

Je veux configurer Nginx en tant que proxy inverse de mise en cache devant Apache/Django: avoir des demandes de proxy Nginx pour certaines (mais pas toutes) les pages dynamiques vers Apache, puis mettre en cache les pages générées et servir les demandes suivantes pour ces pages à partir du cache.

Idéalement, je voudrais invalider le cache de 2 manières:

  1. Définir une date d'expiration sur l'élément mis en cache
  2. Pour invalider explicitement l'élément mis en cache. Par exemple. si mon Django a mis à jour certaines données, je voudrais dire à Nginx d'invalider le cache des pages affectées

Est-il possible de configurer Nginx pour cela? Comment?

145
Continuation

Je ne pense pas qu'il existe un moyen d'invalider explicitement les éléments mis en cache, mais voici un exemple de la façon de faire le reste. Mise à jour: Comme mentionné par Piotr dans une autre réponse, il existe un module de purge du cache que vous pouvez utiliser. Vous pouvez également forcer une actualisation d'un élément mis en cache en utilisant proxy_cache_bypass de nginx - voir réponse de Cherian pour plus d'informations.

Dans cette configuration, les éléments qui ne sont pas mis en cache seront récupérés sur example.net et stockés. Les versions mises en cache seront servies aux futurs clients jusqu'à ce qu'elles ne soient plus valides (60 minutes).

Vos en-têtes HTTP Cache-Control et Expires seront honorés, donc si vous souhaitez définir explicitement une date d'expiration, vous pouvez le faire en définissant les en-têtes corrects dans tout ce que vous utilisez.

Il y a beaucoup de paramètres que vous pouvez régler - voir la documentation du module nginx Proxy pour plus d'informations sur tout cela, y compris des détails sur la signification des différents paramètres/paramètres: http://nginx.org/r/proxy_cache_path

http {
  proxy_cache_path  /var/www/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
  proxy_temp_path /var/www/cache/tmp; 


  server {
    location / {
      proxy_pass http://example.net;
      proxy_cache my-cache;
      proxy_cache_valid  200 302  60m;
      proxy_cache_valid  404      1m;
    }
  }
}
97
Casey

Vous pouvez spécifiquement invalider le cache pages

proxy_cache_bypass       

Dites que vous voulez mettre en cache une page, définissez le cache de cette façon

location = /pageid {
  proxy_pass http://localhost:82;
  proxy_set_header   Host             $Host;
  proxy_set_header   X-Real-IP        $remote_addr;
  proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  proxy_ignore_headers Set-Cookie; 
  proxy_ignore_headers Cache-Control; 
  proxy_cache_bypass        $http_secret_header;
  add_header X-Cache-Status $upstream_cache_status;
}

Maintenant, quand vous voulez invalider cette page et à nouveau mettre en cache

Faites un appel curl secret avec l'en-tête

curl "www.site.com/pageid" -s -I -H "secret_header:true" 

Il l'invalidera et le mettra en cache.

Fonctionne à partir de nginx 0.7.

En prime, le add_header X-Cache-Status peut être utilisé pour vérifier si la page provient du cache ou non.

47
Cherian

Je vous suggère d'essayer Vernis . Varnish est spécifiquement conçu comme un cache de proxy inverse. Il honorera tous les en-têtes de contrôle de cache que vous envoyez depuis le serveur Origin, ce qui satisfait votre première demande.

Pour votre deuxième demande, invalidation explicite. Ma forte recommandation est de changer le nom de l'URL de la ressource que vous souhaitez invalider, soit en renommant le fichier, soit en utilisant une forme de buster de cache de chaîne de requête. Varnish a une opération PURGE qui supprimera la ressource du cache de Varnish, mais elle ne vous donnera aucun contrôle sur les autres caches entre vous et l'utilisateur. Comme vous avez dit que vous souhaitez purger explicitement une ressource, les en-têtes de contrôle http standard ne vous aideront pas. Dans ce cas, la façon la plus infaillible de vaincre la mise en cache d'une ressource est de la renommer.

36
Dave Cheney

Pour invalider les pages sélectionnées, vous pouvez utiliser le patch "cache_purge" pour nginx-0.8.x qui fait exactement ce que vous voulez;)

Il est disponible ici .

8
Piotr Sikora

La plupart des outils de mise en cache (Citrix) permettent un rafraîchissement forcé (Ctrl + r) pour repeupler une page mise en cache.

Voici une astuce que j'ai trouvée pour faire quelque chose de similaire dans nginx.

server  {
        # Other settings
        proxy_pass_header       Set-Cookie; # I want to cache logged-in users
        proxy_ignore_headers    X-Accel-Redirect;
        proxy_ignore_headers    X-Accel-Expires Expires Cache-Control;
        if ($http_cache_control ~ "max-age=0") {set $eac 1;}
        proxy_cache_bypass $eac;
}

Cela suppose que lorsque vous effectuez un Ctrl + r dans votre navigateur, l'en-tête Cache-Control a max-age = 0 dans sa demande. Je sais Chrome fait cela, mais je n'ai pas essayé dans d'autres navigateurs. L'ajout de champs d'en-tête peut être facile, en ajoutant simplement plus d'instructions if qui définissent le $eac variable à 1.

8
Randy Wallace

La mise en cache est une fonction assez nouvelle dans nginx (et pas si bien documentée pour l'instant), mais suffisamment stable pour être utilisée en production.

5
SaveTheRbtz

Je crois que NginxHttpProxyModule est capable de traiter les requêtes http. Recherchez les directives commençant par:

proxy_cache

Oui, il est possible de contrôler le comportement du cache via des directives comme:

proxy_cache_valid
4
Taras Chuhay

Étant donné que vous ne pouvez pas y trouver de documents, je me méfierais un peu de compter dessus en production. Avez-vous pensé au vernis? C'est mon "nginx de procurations inverses", petit, léger, faisant un travail et le faisant bien.

3
womble

Si vous utilisez des eTags sur votre application et que vous placez nginx devant, il prendra soin de l'expiration pour vous, car si l'eTag change, il invalidera le cache.

2
Martin Murphy

Vous pouvez contrôler l'expiration du cache de Nginx avec plusieurs directives/paramètres:

  • proxy_cache_valid 200 302 10m;
  • en ajoutant l'un des en-têtes HTTP ci-dessous (la priorité est importante - consultez mon article de blog ):
    • Expires
    • Cache-Control
    • X-Accel-Expires
  • le paramètre inactive dans le proxy_cache_path directive:

    proxy_cache_path /data/nginx/cache keys_zone=one:10m inactive=60m;

Je recommande mon article de blog si vous souhaitez en savoir plus sur la mise en cache Nginx.

Le sujet de purge est vraiment intéressant car cette fonctionnalité n'existe que dans Nginx Plus (l'édition commerciale de Nginx). J'aime vraiment la réponse de @ randy-wallace. Mais il existe aussi d'autres possibilités comme le module ngx_cache_purge .

La chose la plus simple que vous pouvez faire est de supprimer manuellement le fichier mis en cache:

  • générer votre clé de hachage:

    echo -n ‘httpczerasz.com/time.php’ | md5sum
    
  • supprimez le fichier du système de fichiers:

    rm /data/nginx/cache/1/27/2bba799df783554d8402137ca199a271
    
2
czerasz

Pour les futurs visiteurs: Pendant ce temps, le proxy inverse nginx a intégré la mise en cache et les documents sont disponibles sur:

Syntaxe: zone proxy_cache | de;

Par défaut: proxy_cache off;

Contexte: http, serveur, emplacement

Définit une zone de mémoire partagée utilisée pour la mise en cache. La même zone peut être utilisée à plusieurs endroits. La valeur du paramètre peut contenir des variables (1.7.9). Le paramètre off désactive la mise en cache héritée du niveau de configuration précédent.

2
Tarik Huclaslun
 fastcgi_cache_path/opt/nginx-cache levels = 2: 2 keys_zone = img: 50m; 
 
 location/img/{
 fastcgi_pass $ backend; 
 comprennent fcgi_params; 
 fastcgi_intercept_errors off; 
 fastcgi_cache_key $ server_addr $ request_uri; 
 fastcgi_cache img; 
 fastcgi_cache_valid any 1m; 
 fastcgi_hide_header Set-Cookie; 
} 

Cela crée un cache pour/img/location. Il se trouve dans/opt/nginx-cache. Les objets sont mis en cache pendant 1 minute.

Vous pouvez écrire différents codes de réponse au lieu de n'importe lequel.

Maintenant, vous ne pouvez pas invalider le cache pour les pages sélectionnées. Peut-être qu'en 0.8.x ce sera possible.

0
lexsys

Il existe un plugin nginx appelé ncache qui prétend être "une base de système de cache Web sur le serveur Web nginx. Plus rapide et plus efficace que Squid".

0
sajal