Comment configurer Nginx en tant que proxy inverse de mise en cache?

143

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

Je souhaite configurer Nginx en tant que proxy inverse de mise en cache devant Apache / Django: pour avoir des requêtes de proxy Nginx pour certaines pages dynamiques (mais pas toutes) vers Apache, puis pour mettre en cache les pages générées et pour servir les demandes ultérieures de 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. Invalider explicitement l'élément mis en cache. Par exemple, si mon serveur 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 le faire? Comment?

Continuation
la source
Non testé, mais à l' adresse gumroad.com/l/ngx_purge : "ngx_purge est un module pur Lua pour Nginx qui permet à l'utilisateur de purger un objet du cache nginx.".
Jaime Hablutzel

Réponses:

97

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

Dans cette configuration, les éléments qui ne sont pas mis en cache seront extraits de 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 HTTP seront respectés. Par conséquent, 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 transmettez par proxy.

Vous pouvez régler de nombreux paramètres. Pour plus d’informations sur cette opération, reportez-vous à la documentation du module Proxy de nginx, notamment 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;
    }
  }
}
Casey
la source
7
C'est une première étape raisonnable pour les nouvelles applications qui n'ont pas 20k / req / s.
5
@Barry, quel sera le deuxième pas?
Jürgen Paul
42
@ Legit - Je ne sais pas, mais traditionnellement, la dernière étape est le "profit" :-)
Stephen C
Malheureusement, cela ne fonctionne pas avec nginx 1.11. Depuis la dernière mise à jour, il y a environ 3 ans, il semble que ce ne soit plus la solution.
izogfif
Que signifie le: inactive=600msignifie? N'est-ce pas inactivesupposé être le temps? `[inactive=time]
NeverEndingQueue
47

Vous pouvez spécifiquement invalider les pages en cache via

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 mettre en cache à nouveau

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

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

Il sera invalidé et mis en cache.

Fonctionne à partir de nginx 0.7.

En prime, vous add_header X-Cache-Statuspouvez vérifier si la page est en cache ou non.

Cherian
la source
Cela ne peut mettre à jour les pages mises en cache que lorsque la nouvelle page peut également être mise en cache. Si vous avez supprimé une page (404 ou d'autres erreurs sont maintenant résolues par le backend), la page envoie maintenant un en-tête Set-Cookie ou un en-tête "Content-Control: private", le contenu mis en cache ne sera pas "invalidé".
Rubu
36

Je vous suggère d' essayer Varnish . 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 à partir du serveur d'origine, ce qui satisfait votre première demande.

Pour votre deuxième demande, invalidation explicite. Ma recommandation est fortement 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 bus de cache de chaîne de requête. Varnish a une PURGEopération qui supprimera la ressource du cache de Varnish, mais elle ne vous donnera pas le contrôle sur les autres caches entre vous et l'utilisateur. Comme vous avez dit vouloir purger explicitement une ressource, les en-têtes de contrôle http standard ne vous aideront pas. Dans ce cas, le moyen le plus sûr de vaincre la mise en cache d'une ressource est de la renommer.

Dave Cheney
la source
Pourriez-vous expliquer ce que vous vouliez dire par "renommer le fichier ou utiliser une forme de requête de cache de chaînes de requête"? Je ne suis pas sûr de comprendre pourquoi ce n'est pas une bonne idée d'utiliser une opération comme PURGE.
Suite le
5
+1 pour le vernis. Il est toujours préférable d'utiliser les bons outils pour le travail.
Tom O'Connor
4
@below: Il n'y a presque aucun espoir de toucher au vernis dans les domaines de la performance et de la polyvalence. Ceci est soutenu par l’un des principaux développeurs du noyau FreeBSD et une équipe dédiée basée en Europe. Le vernis est en production sur twitter, heroku et beaucoup d'autres.
2
L'exemple le plus simple d'un cache-buster consiste à ajouter un numéro de version dans une chaîne de requête à une ressource statique, afin que style.css devienne style.css? 123. Lorsque vous souhaitez publier une nouvelle version du fichier, vous modifiez l'URL de la ressource en style.css? 124. Les caches la récupèrent désormais comme un tout nouvel élément à mettre en cache séparément. Apache servira le fichier style.css avec n'importe quelle chaîne de requête ajoutée. Par conséquent, aucune modification du fichier n'est requise.
chmac
3
Si possible, il est préférable de placer le bus de cache dans le nom du fichier lui-même, par exemple style.v123.cssparce que certains caches ne mettront pas en cache les demandes comportant une chaîne de requête.
Noah McIlraith le
8

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

C'est disponible ici .


la source
8

La plupart des outils de mise en cache (Citrix) autorisent une actualisation forcée (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 faites un Ctrl + r dans votre navigateur, l'en-tête Cache-Control a max-age = 0 dans sa demande. Je sais que Chrome le fait, mais je n'ai pas essayé dans d'autres navigateurs. Il est facile d’ajouter d’autres champs d’en-tête, il suffit d’en ajouter d’autres si les instructions définissent la $eacvariable sur 1.

Randy Wallace
la source
5

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

SaveTheRbtz
la source
4

Je crois que NginxHttpProxyModule est capable d’appeler 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 telles que:

proxy_cache_valid
Taras Chuhay
la source
3

Sur la base du fait que vous ne pouvez pas trouver de documents sur celui-ci, je serais un peu méfiant quant à son utilisation en production. Avez-vous envisagé de vernir? C'est mon "nginx des proxys inverses", petit, léger, qui fait un travail et le fait bien.

femme
la source
La documentation est ici: wiki.nginx.org/NginxHttpProxyModule#proxy_cache
rmalayter le
2

Si vous utilisez les balises eTags sur votre application et que vous placez nginx devant elle, elle se chargera de l'expiration, car si l'eTag change, le cache sera invalidé.

Martin Murphy
la source
Vraiment? Il semble que ngnix correspond à l'etag et ne parle jamais à l'application pour savoir s'il existe un etag mis à jour.
John Naegle
2

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

  • proxy_cache_valid 200 302 10m;
  • ajouter 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 inactiveparamètre dans la proxy_cache_pathdirective:

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

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

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

La chose la plus simple que vous puissiez faire est de supprimer manuellement le fichier 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
    
Czerasz
la source
1

Pour les futurs visiteurs: En attendant, le proxy inverse nginx intègre la mise en cache. Les documents sont disponibles à l'adresse suivante:

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.

Tarik Huclaslun
la source
Bonjour Tarik, la question était très précise sur ce qui devait être accompli, et c'est un peu au-delà de "Activer simplement le cache".
asdmin
0
fastcgi_cache_path / opt / nginx-cache levels = 2: 2 keys_zone = img: 50m;

    emplacement / img / {
        fastcgi_pass $ backend;
        inclure 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. C'est 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 que dans 0.8.x ce sera possible.

Lexsys
la source
La question initiale concernait l'utilisation de nginx devant Apache et non devant une application fastcgi gérée par nginx.
Graham Dumpleton
0

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

sajal
la source