Geeek - Le blog Geek & High-tech

Vous développez une application PHP à fort trafic ? Vous ne souhaitez pas que vos workers PHP soient sollicités à chaque requête entrante pour permettre une sollicitation HTTP plus importante ? Il y a pour cela plusieurs solutions :

  • Soit vous prévoyez d'utiliser un CDN si vous prévoyez un trafic très important provenant de plusieurs pays dans le monde.
  • Soit vous prévoyez d'utiliser un frontal Varnish / Squid qui se chargera du cache ce qui rajoute une cache réseau supplémentaire dans la chaîne d'appel des pages hors cache. Il faudra cependant de prévoir lui aussi de le redonder ...
  • Soit vous utilisez le module Fascgi_cache de NGINX si vous utilisez NGINX comme serveur Web.
    Dans cet article je vais vous montrer comment mettre en place le cache NGINX Fastcgi pour mettre en cache les ressources retournées par PHP FPM afin de limiter les sollicitations inutiles et consommatrices de CPU au pool PHP-FPM.

Dans un premier temps vous devez définir une zone de stockage de votre cache dans le fichier nginx.conf, celui-ci aura comme rôle de stocker l'ensemble des éléments mis en cache.
La taille du cache est à adapter en fonction de la taille de votre site Web et de la quantité de pages à mettre en cache.


fastcgi_cache_path /var/nginx/cache/ levels=1:2 keys_zone=microcache:10m max_size=1024m inactive=1h;

Une fois cette étape réalisée, vous devrez préciser l'utilisation de cache à l'endroit où vous sollicitez PHP FPM dans votre vhost :


location ~ \.php$ {
fastcgi_cache  microcache;
fastcgi_cache_key $scheme$host$request_uri$request_method;
fastcgi_cache_valid 200 301 302 5m;
fastcgi_cache_use_stale updating error timeout invalid_header http_500;

fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;

add_header X-Cache $upstream_cache_status;

.... etc
}

Vous devez maintenant jouer avec la variable no_cache pour définir une priorité de cache à NGINX en fonction des contraintes de votre site Web :


#Cache everything by default
set $no_cache 0;

#Don't cache if the URL contains a query string
if ($query_string != ""){
    set $no_cache 1;
}

#Don't cache if there is a cookie called PHPSESSID
if ($http_cookie ~* "PHPSESSID"){
    set $no_cache 1;
}

Une fois ces modifications réalisées vous n'aurez plus qu'à redémarrer la configuration de NGINX et faire un test :


$ sudo /etc/init.d/nginx reload
$ curl -X GET -I https://localhost

Si le header HTTP "X-Cache: HIT" est retourné après plusieurs appels, c'est gagné !
La durée du cache peut être ensuite adaptée via le paramètre : fastcgi_cache_valid

Pour plus de performances et limiter les I/O sur votre disque, vous pouvez créer un disque en mémoire afin qu'aucune lecture / écriture au cache sur votre disque ne soit réalisée par NGINX .

Pour cela, arrêtez le processus Nginx :


$ sudo /etc/init.d/nginx stop

Montez le répertoire de cache sur une partition TMPFS en mémoire :


mount -t tmpfs -o size=1G tmpfs /var/nginx/cache/

Redémarrez le processus NGINX :


$ sudo /etc/init.d/nginx start

Pour permettre à ce montage d'être réalisé automatiquement à chaque démarrage de votre serveur, la modification de votre fichier fstab s'impose :


$ nano -w /etc/fstab

```/

Ajoutez la ligne suivante à votre fichier en faisant attention à ce que la taille du disque corresponde à la taille du cache défini dans __NGINX__ : 
```bash

tmpfs /var/nginx/cache/ tmpfs defaults,size=1G 0 0

Vous voilà avec un serveur NGINX équipé d'un cache capable de restituer des pages HTML au lieu du pool PHP qui lui est très consommateur en CPU et en ressources.

Pour allez plus loin dans votre tuning, vous pouvez ajoutez les "proxy pass" en cache si votre serveur agit en reverse proxy :


proxy_cache            STATIC;
proxy_cache_valid      200  1d;
proxy_cache_use_stale  error timeout invalid_header updating
                                   http_500 http_502 http_503 http_504;

Mais aussi en ajoutant les fichiers statiques en cache :


open_file_cache          max=10000 inactive=5m;
open_file_cache_valid    2m;
open_file_cache_min_uses 1;
open_file_cache_errors   on;

Enfin, pour terminer et pour vous débarrasser des IO inutiles sur votre serveur qui sont souvent le goulot d'étranglement de votre système, vous pouvez faire en sorte qu'OPCache garde tous vos fichiers PHP en cache mémoire.
Pour cela, assurez-vous que votre module OPCache est fonctionnel et positionnez les paramètres suivants dans le fichier .ini dédié au module OPCache. Après un redémarrage de PHP FPM, les fichiers PHP seront gardés en mémoire et plus aucune vérification de mise à jour de ces fichiers ne sera réalisée par PHP. Cela signifie que vous devrez redémarrer PHP-FPM à chaque modification de code PHP pour que celle-ci soit prise en compte.


opcache.memory_consumption=128 # MB, adjust to your needs
opcache.max_accelerated_files=10000 # Adjust to your needs
opcache.max_wasted_percentage=10 # Adjust to your needs
opcache.validate_timestamps=0


Vous êtes correctement abonné à Geeek
Bienvenue ! Vous êtes correctement connecté.
Parfait ! Vous êtes correctement inscrit.
Votre lien a expiré
Vérifiez vos emails et utiliser le lien magique pour vous connecter à ce site