Mise en cache de base avec Nginx : améliorer les temps de réponse
Configurez la mise en cache proxy de base de Nginx en toute sécurité avec des zones de cache, des TTL, des règles de contournement, des en-têtes de statut et des étapes de test.
Mise en cache de base avec Nginx : améliorer les temps de réponse
La mise en cache de base avec Nginx peut améliorer les temps de réponse en sauvegardant une copie des réponses en amont et en les servant à nouveau sans interroger l'application à chaque fois. Utilisée avec précaution, la mise en cache réduit la charge du backend, lisse les pics de trafic et rend les requêtes répétées plus rapides.
La mise en cache n'est pas réservée aux grands sites. Même une petite application peut en bénéficier lorsque des pages, des réponses API ou des fichiers statiques sont demandés fréquemment et ne changent pas à chaque seconde.
Ce que Nginx peut mettre en cache
Nginx peut mettre en cache les réponses d'un serveur amont lorsqu'il agit comme proxy inverse. Cela diffère de la mise en cache normale du navigateur. La mise en cache du navigateur stocke les fichiers sur l'appareil de l'utilisateur. La mise en cache proxy de Nginx stocke les réponses sur le serveur afin que de nombreux utilisateurs puissent bénéficier de la même copie mise en cache.
Une configuration simple de cache proxy comporte deux parties. Tout d'abord, définissez une zone de cache dans le bloc http :
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:10m
max_size=1g inactive=60m use_temp_path=off;
Ensuite, activez ce cache dans un bloc server ou location :
location / {
proxy_pass http://127.0.0.1:3000;
proxy_cache app_cache;
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
}
La directive proxy_cache_path crée la zone de stockage du cache. keys_zone définit la mémoire partagée pour les clés de cache et les métadonnées. max_size limite l'utilisation du disque. inactive supprime les éléments qui n'ont pas été consultés depuis un certain temps.
Les directives proxy_cache_valid déterminent combien de temps certains codes de réponse restent en cache. Dans l'exemple, les réponses réussies sont mises en cache pendant 10 minutes, tandis que les réponses 404 sont mises en cache pendant 1 minute.
L'en-tête X-Cache-Status est utile lors des tests. Il peut afficher des valeurs telles que MISS, HIT, BYPASS ou EXPIRED, selon ce qui s'est passé.
Pour les sites qui utilisent également Nginx comme proxy inverse, cela se marie naturellement avec la configuration du proxy inverse.
Décider ce qui doit être mis en cache
La partie la plus difficile de la mise en cache avec Nginx n'est pas d'écrire les directives. C'est de décider quel contenu peut être réutilisé en toute sécurité.
Les bons candidats à la mise en cache incluent :
- Pages marketing publiques.
- Pages de documentation publiques.
- Pages de listes de produits qui se mettent à jour selon un calendrier prévisible.
- Réponses API anonymes.
- Réponses amont coûteuses qui sont identiques pour de nombreux utilisateurs.
Les mauvais candidats à la mise en cache incluent :
- Pages de compte.
- Paniers d'achat.
- Écrans d'administration.
- Réponses qui incluent des données utilisateur privées.
- Pages qui changent en fonction des cookies ou des en-têtes d'autorisation.
Si une réponse est différente pour chaque utilisateur, ne la mettez pas en cache à moins d'avoir une stratégie de clé de cache très claire. Servir accidentellement la réponse privée d'un utilisateur à un autre utilisateur est un bug grave.
Vous pouvez contourner la mise en cache lorsque les requêtes incluent des données de session ou d'autorisation :
proxy_cache_bypass $http_authorization;
proxy_no_cache $http_authorization;
Pour les sessions basées sur les cookies, vous pouvez utiliser un modèle similaire :
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
Le nom exact du cookie dépend de votre application. Ne copiez pas cela aveuglément sans vérifier comment votre application gère les sessions.
Un scénario pratique : votre page d'accueil de blog public est générée par une application et prend 300 millisecondes un jour chargé. Si vous mettez cette page en cache pendant 5 minutes, la plupart des visiteurs reçoivent la copie mise en cache rapidement, et l'application ne la régénère qu'occasionnellement. C'est un cas d'utilisation solide car la page d'accueil est publique et non spécifique à un utilisateur.
Clés de cache, en-têtes et purge
Nginx utilise une clé de cache pour décider si deux requêtes doivent partager la même réponse mise en cache. La clé de cache par défaut est généralement basée sur le schéma, la méthode, l'hôte et l'URI. Pour de nombreux sites, cela suffit.
Si les chaînes de requête modifient la réponse, assurez-vous qu'elles font partie de la clé. Si les chaînes de requête ne sont que des paramètres de suivi, vous pouvez les normaliser au niveau de l'application ou du CDN plutôt que de laisser chaque utm_source créer une entrée de cache distincte.
Les en-têtes de cache amont comptent également. Votre application peut envoyer des en-têtes tels que :
Cache-Control: public, max-age=600
ou :
Cache-Control: private, no-store
Nginx peut être configuré pour respecter ou remplacer ces en-têtes, mais vous devez choisir une politique claire. Si les développeurs de l'application s'attendent à ce que Cache-Control: no-store empêche la mise en cache, remplacer ce comportement au niveau de Nginx peut créer des résultats déroutants et risqués.
La purge est une autre question opérationnelle. Nginx open source n'inclut pas de point de terminaison de purge de cache intégré simple comme certains modules commerciaux ou tiers. De nombreuses équipes gèrent cela en utilisant des durées de cache courtes, des URL versionnées ou des scripts de déploiement qui effacent le répertoire de cache lors des versions contrôlées.
Les TTL courts sont souvent suffisants. Un cache de 60 secondes sur un point de terminaison chargé peut encore supprimer une grande quantité de trafic backend tout en gardant le contenu raisonnablement frais.
Tester le comportement du cache
Après avoir activé la mise en cache, demandez la même URL plusieurs fois et inspectez les en-têtes de réponse :
curl -I https://example.com/
Si vous avez ajouté X-Cache-Status, la première requête peut afficher MISS, et les requêtes suivantes devraient afficher HIT. Si chaque requête est un MISS, vérifiez les en-têtes de réponse, les règles de contournement du cache, les cookies de requête et si le répertoire de cache est accessible en écriture par le processus de travail Nginx.
Testez également le comportement connecté et déconnecté. C'est là que de nombreuses erreurs de mise en cache apparaissent. Ouvrez une fenêtre de navigation privée, connectez-vous en tant qu'utilisateur de test et confirmez que les pages privées ne sont pas mises en cache publiquement.
Surveillez également l'utilisation du disque. Un cache sans limite pratique peut remplir un système de fichiers. Utilisez max_size, gardez le stockage du cache séparé des partitions système critiques lorsque cela est possible, et alertez en cas de pression sur le disque.
Quand demander de l'aide
Faites appel à un ingénieur Nginx ou plateforme expérimenté si le contenu mis en cache apparaît sous le mauvais utilisateur, si votre taux de succès du cache reste faible après réglage, ou si les fichiers de cache remplissent le disque de manière inattendue. Les problèmes de mise en cache peuvent sembler simples tout en cachant un comportement spécifique à l'application.
Vous devriez également demander de l'aide avant de mettre en cache des API authentifiées, des tableaux de bord multi-locataires ou des flux liés aux paiements. Ces domaines nécessitent une conception minutieuse.
La mise en cache de base avec Nginx fonctionne mieux lorsque vous commencez avec des réponses publiques et répétables et des durées de cache courtes. Ajoutez des en-têtes de statut de cache visibles pendant les tests, respectez les limites du contenu privé, et mesurez à la fois le temps de réponse et la charge du backend. Bien fait, la mise en cache offre aux utilisateurs des pages plus rapides tout en donnant à votre application de la marge de manœuvre.