Pagespeed : Microcaching avec Nginx

Nginx est un serveur web très rapide en soi, mais il offre également des fonctions intéressantes de mise en cache, qui minimisent l'accès à PHP et permettent de livrer les pages beaucoup plus rapidement. Un petit guide.

Pour ce blog, j'utilise la version actuelle de Nginx mainline 1.7.0 avec les modules ngx_pagespeed comme base. Pour cela, j'ai dû compiler nginx moi-même, mais ce n'est pas un problème fondamental et cela peut être fait rapidement avec les instructions appropriées, même sur un système Debian actuel.
Voici mes paramètres de configuration :

--prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.verrouiller --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module -...--with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_spdy_module --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,--as-needed' --with-ipv6 --add-module=../ngx_pagespeed-1.7.30.4-beta --add-module=../ngx_cache_purge-2.1

Cela permet d'utiliser nginx 1.7.0 en remplacement de nginx des dépôts Debian, tous les répertoires de configuration restant les mêmes. Si quelque chose ne va pas avec la version auto-compilée, vous pouvez aussi simplement revenir à la version originale.

Préparation au microcaching

Pour que nginx puisse utiliser le microcaching, la configuration doit être adaptée. Pour ce faire, dans le dossier /etc/nginx/conf.d créer un nouveau fichier, je l'ai appelé microcache.conf. Il est automatiquement chargé dans le fichier de configuration principal. Le contenu de ce fichier :

fastcgi_cache_path /dev/shm/microcache levels=1:2 keys_zone=microcache:5M max_size=1G inactive=2h ;
fastcgi_cache_key "$scheme$request_method$host$request_uri" ;
fastcgi_cache_use_stale error timeout invalid_header http_500 ;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie ;

Cela crée une zone de cache d'un gigaoctet appelée "microcache" dans un disque RAM. Si vous ne pouvez ou ne voulez pas conserver le cache dans la RAM, vous pouvez bien sûr créer un répertoire sur le disque dur et l'utiliser. La clé de chaque entrée du cache résulte du protocole, de la méthode de requête (POST ou GET), de l'hôte et de l'URL appelée. Cela signifie que plusieurs blogs WordPress peuvent être mis en cache sans se chevaucher.

Configuration de la mise en cache pour VirtalHosts

La plupart des gens travailleront avec une configuration VirtualHost. Pour que la sortie de PHP soit mise en cache, fastcgi doit être configuré en conséquence. Les informations suivantes doivent être ajoutées au fichier de configuration correspondant :

set $skip_cache 0 ;

# Les requêtes POST et les urls contenant une chaîne de requête doivent toujours être envoyées à PHP.
if ($request_method = POST) {
 set $skip_cache 1 ;
}

si ($query_string != "") {
 set $skip_cache 1 ;
}

# Ne pas mettre en cache les uris contenant les segments suivants
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index) ?.xml {
set $skip_cache 1 ;
    }

# Ne pas utiliser le cache pour les utilisateurs connectés ou les commentateurs récents
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1 ;
}

emplacement / {
try_files $uri $uri/ /index.php?$args ;
}

# traite tous les scripts php, ceux qui ne sont pas trouvés sont redirigés par routestring.
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(.*)$ ;
fastcgi_index index.php ;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name ;
fastcgi_cache microcache ;
fastcgi_cache_bypass $skip_cache ;
fastcgi_no_cache $skip_cache ;
# Définir la clé du cache pour inclure les éléments d'identification
fastcgi_cache_valid 200 1d ;
fastcgi_cache_valid 302 301 1m ;
fastcgi_cache_valid 404 1s ;
fastcgi_cache_min_uses 1 ;
fastcgi_cache_use_stale error timeout invalid_header updating http_500 ;
fastcgi_ignore_headers Cache-Control Expires ;
fastcgi_pass_header Set-Cookie ;
cookie fastcgi_pass_header ;
}

Conclusion

Par rapport à la solution que j'ai utilisée jusqu'à présent (Mise en cache de pages entières via Memcached), la variante via les fonctions de mise en cache intégrées à Nginx offre quelques avantages :

  • Aucun accès à PHP-FPM pour livrer à partir du cache.
  • Les pages peuvent également être livrées si PHP renvoie une erreur (ceci est indiqué par la ligne fastcgi_cache_use_stale atteint)
  • Pour WordPress, il existe des plugins adaptés qui facilitent le vidage du cache (purge cache).

Je vais continuer à utiliser cette configuration ici dans le blog et voir quels autres effets elle a - les temps de chargement rapides sont déjà un avantage fondamental.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *