Menu Fermer

Optimiser le cache de Nginx

Nginx est un serveur WEB très performant qui a grâce à sa rapidité a réussi à détrôner Apache.
Il offre énormément de directives de cache pour optimiser le serveur WEB et gagner en vitesse.
Que vous aillez un contenu statique, dynamique, WordPress, Joomla ou autres CMS, grâce au cache Nginx, vous pouvez améliorer les temps de réponse et vitesse de chargement de vos pages WEB.

Dans ce tutoriel complet, je vous donne tous les réglages à faire sur le cache Nginx pour une vitesse maximale de votre site WEB.

Optimiser le cache de Nginx

Optimiser le cache de Nginx

Pour la mise en place et configuration générale du cache Nginx, suivez ce tutoriel :

Les buffers

Les buffers sont des tampons en mémoire pour stocker des données en bénéficiant de la vitesse de la mémoire RAM.
En augmentant, les tampons, cela peut améliorer les temps de réponse selon les besoins de vos applications.
Mais le serveur WEB va utiliser plus de mémoire.
De plus, des valeurs trop hautes, peut aussi aider à faire tomber plus facilement votre serveur WEB par une attaque par déni de service.
ils font donc trouver le bon équilibre entre performances et mémoire disponible.

  • client_body_buffer_size : définit la taille de la mémoire tampon pour la lecture du corps de la requête client. Si le corps de la requête est plus grand que le tampon, le corps entier ou seulement sa partie est écrit dans un fichier temporaire. La valeur doit être réglé sur la limite de la taille d’un fichier en upload
  • client_header_buffer_size : tampon pour la lecture de l’en-tête HTTP de demande du client
  • client_max_body_size : la taille maximale autorisée du corps de la demande client. Si la taille d’une requête dépasse la valeur configurée, l’erreur 413 (Request Entity Too Large) est renvoyée au client
  • large_client_header_buffers : La taille maximum des tampons utilisés pour la lecture d’un en-tête de requête client volumineux. Une ligne de demande ne peut pas dépasser la taille d’un tampon, ou l’erreur 414 (Request-URI Too Large) est renvoyée au client. Un champ d’en-tête de demande ne peut pas non plus dépasser la taille d’un tampon, sinon l’erreur 400 (Mauvaise demande) est renvoyée au client

Dans Nginx, il existe le tampon d’en-tête HTTP par défaut qui est configuré avec la directive client_header_buffer_size. Lorsqu’une requête arrive, les en-têtes sont d’abord lus dans ce tampon, les large_client_header_buffers ne sont pas engagés tant que la taille totale des en-têtes de requête ne dépasse pas la valeur configurée pour client_header_buffer_size, par défaut 1 Ko.

En général, on préconise ces réglages mais cela dépend de vos besoins.

client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 4 4k;

On préconise aussi la formule suivant qui s’approche de celle pour optimiser PHP-FPM :

MAX_RAM = client_body_buffer_size X concurrent_traffic - OS_RAM - FS_CACHE.

Proxy buffers

Par défaut, NGINX met en mémoire tampon les réponses des serveurs proxy. Une réponse est stockée dans les tampons internes et n’est envoyée au client qu’une fois la réponse complète reçue.
La mise en mémoire tampon permet d’optimiser les performances avec les clients lents, ce qui peut faire perdre du temps au serveur proxy si la réponse est transmise de NGINX au client de manière synchrone.
Cependant, lorsque la mise en mémoire tampon est activée, NGINX permet au serveur proxy de traiter les réponses rapidement, tandis que NGINX stocke les réponses aussi longtemps que les clients ont besoin de les télécharger.

  • proxy_buffers : Définit le nombre et la taille des tampons utilisés pour lire une réponse du serveur proxy, pour une seule connexion. Par défaut, la taille du tampon est égale à une page mémoire. Il s’agit de 4K ou de 8K, selon la plate-forme.
  • proxy_buffer_size : Définit la taille du tampon utilisé pour lire la première partie de la réponse reçue du serveur proxy. Cette partie contient généralement un petit en-tête de réponse. Par défaut, la taille du tampon est égale à une page mémoire. Il s’agit de 4K ou de 8K, selon la plate-forme. Il peut cependant être réduit. Cette valeur est à augmenter, si vous rencontrez l’erreur too big header while reading response header from upstream.
  • proxy_busy_buffers_size : Lorsque la mise en mémoire tampon des réponses du serveur proxy est activée, limite la taille totale des tampons pouvant être occupés à envoyer une réponse au client alors que la réponse n’est pas encore entièrement lue. En attendant, le reste des tampons peut être utilisé pour lire la réponse et, si nécessaire, mettre en mémoire tampon une partie de la réponse dans un fichier temporaire. Par défaut, la taille est limitée par la taille de deux tampons définie par les directives proxy_buffer_size et proxy_buffers
  • proxy_max_temp_file_size : il s’agit de la taille maximale, par requête, pour un fichier temporaire sur le disque. Ceux-ci sont créés lorsque la réponse en amont est trop grande pour tenir dans un tampon.
  • proxy_temp_file_write_size : c’est la quantité de données que Nginx écrira dans le fichier temporaire à un moment donné lorsque la réponse du serveur proxy est trop grande pour les tampons configurés.
  • proxy_temp_path : il s’agit du chemin d’accès à la zone du disque où Nginx doit stocker tous les fichiers temporaires lorsque la réponse du serveur en amont ne peut pas tenir dans les tampons configurés.
Si votre nginx fait un proxy pass vers PHP-FPM, il faut alors optimiser les valeurs fastcgi_buffers, fastcgi_buffer_size, fastcgi_busy_buffers_size en suivant la même logique.

La taille proxy_buffers doit être choisie pour éviter les E/S disque. Si la taille de la réponse est supérieure à (proxy_buffers size + proxy_buffer_size), la réponse peut être écrite sur le disque, augmentant ainsi les E/S, le temps de réponse, etc.

Pour vous aider à calculer la bonne valeur proxy_buffers, utilisez curl pour récupérer la taille de l’en-tête HTTP :

curl -s -w \%{size_header} -o /dev/null "https://www.malekal.com" -H "Accept-Encoding: gzip"

Pour définir proxy_buffers, il faut déterminer la taille d’une page WEB, par exemple avec curl :

curl -so /dev/null https://forum.malekal.com/ -w '%{size_download}'

Si vous retournez systématiquement du contenu compressé alors :

curl --compressed -so /dev/null https://forum.malekal.com/ -w '%{size_download}'

Dans mon cas, cela retourne 65872 (65k).
On peut alors définir les valeurs en divisant par le nombre de buffers.

proxy_buffers 8 8k; # 64-bits
proxy_buffers 4 16k; # 32-bits

Désactiver proxy buffering

proxy_busy_buffers_size correspond à a mise en mémoire tampon des réponses du serveur proxy.

Lorsque la mise en mémoire tampon est activée, Nginx reçoit une réponse du serveur proxy dès que possible, l’enregistrant dans les tampons définis par les directives proxy_buffer_size et proxy_buffers.
Si la réponse entière ne tient pas dans la mémoire, une partie peut être enregistrée dans un fichier temporaire sur le disque.
Si la mise en mémoire tampon est désactivée, la réponse est envoyée au client de manière synchrone pendant qu’il la reçoit du serveur proxy. Vous pouvez donc abaisser le Time To First Byte (TTFB).

Lorsque la mise en mémoire tampon est désactivée, la réponse est transmise à un client de manière synchrone, dès sa réception. nginx n’essaiera pas de lire l’intégralité de la réponse du serveur proxy. La taille maximale des données que nginx peut recevoir du serveur à la fois est définie par la directive proxy_buffer_size.

Activer la compression Gzip

Il existe deux méthodes de compression GZIP et Brotli des pages WEB.
Ce dernier est plus efficace mais n’est pas inclut par défaut dans nginx.
Il faut recompiler ce dernier ou trouver un paquet pour votre distribution Linux.

Cela réduit fortement la taille des pages WEB pour accélérer le transfert.

Pour activer GZIP sur Nginx :

    gzip on;
    # gzip_static on;
    gzip_min_length 10240;
    gzip_buffers 16 8k;
    gzip_comp_level 2;
    gzip_vary on;
    gzip_disable msie6;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types
        # text/html is always compressed by HttpGzipModule
        text/css
        text/javascript
        text/xml
        text/plain
        text/x-component
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/rss+xml
        application/atom+xml
        font/truetype
        font/opentype
        application/vnd.ms-fontobject
        image/svg+xml;

Mettre en place un cache statique

Ensuite il faut configurer la mise en cache statique pour le navigateur internet.
Ainsi, les fichiers statiques seront téléchargés dans le navigateur WEB. Lors du retour sur le site, ils ne seront plus télécharger sur le site, ce qui permet de gagner en vitesse de chargement de la page.

Voici un exemple pour définir une mise en cache par extension de fichiers.
On désactive aussi les journaux pour limiter les accès disque.

location ~* ^.+\.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|woff2|webp)$ {
                access_log off;
                log_not_found off;
                add_header Cache-Control "public, no-transform";
                expires 365d;
        }

Microcaching avec tmpfs

Le contenu dynamique ne peut être mis en cache, du moins trop longtemps, puisque ce dernier temps à être modifié régulièrement.
Mais pour diminuer le TTFB ou Time To First Byte, vous pouvez utiliser la technique de est le microcaching.
Cela consiste à définir un délai de cache très court entre 1 et 10s.
C’est une méthode efficace pour accélérer la livraison de contenu dynamique et non personnalisé en le mettant en cache pendant de très courtes périodes.
Cela peut accélérer une application basée sur WordPress jusqu’à 400 fois en utilisant la technique de microcaching.

Par exemple sur PHPBB, un forum à contenu dynamique, lorsque la page est en cache, le DOM se charge en moins de 600 ms.

Microcaching avec tmpfs pour diminuer le temps de chargement des pages WEB

Lorsque la page n’est pas en cache, le temps de chargement du DOM dépasse les 2s.

Microcaching avec tmpfs pour diminuer le temps de chargement des pages WEB

Voici comment mettre en place un microcaching en mémoire grâce à tmpfs.

  • Tout d’abord on créé le répertoire suivant :
mkdir -p /var/cache/nginx/ramcache
  • Puis on le monte en mémoire :
mount -t tmpfs -o size=2G tmpfs /var/cache/nginx/ramcache
  • Modifiez /etc/fstab afin de le recréer au démarrage du serveur :
tmpfs /var/cache/nginx/ramcache tmpfs defaults,size=2G 0 0
  • Puis on créé la zone de microcaching qui sera stocké dans cet espace :
fastcgi_cache_path /var/cache/nginx/ramcache/fastcgi_temp/ levels=1:2 keys_zone=cachezone:100m max_size=2g inactive=60m use_temp_path=off;
  • Ensuite pour l’appeler dans la directive server :
fastcgi_cache_key $scheme$request_method$host$request_uri;
proxy_cache_lock on;
proxy_cache_use_stale updating;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
  • Enfin relancez le service nginx :
/etc/init.d/nginx restart
Notez qu’il existe des modules Nginx pour utiliser memcached ou redis comme emplacement de cache.