Modifier la limite de fichiers sur ubuntu 16.x pour nginx et fpm

Le système de gestion des limites a évolué et utiliser /etc/security/limits.conf n’est plus valide sur ubuntu 16 car le système de gestion de service est maintenant basé sur systemd.

Le plus frustrant c’est qu’à première vue rien a changé : dans /etc/init.d/ on retrouve nos scripts de lancement classique mais effectivement on observe un if systemd qui peux mettre la puce à l’oreille. En effet, l’installateur de paquet a fait son travail et a mis en place les fichiers de service compatible avec systemd. Il faut donc aller voir du côté de  /etc/systemd/system/multi-user.target.wants pour trouver nos services fpm et nginx.

# ll /etc/systemd/system/multi-user.target.wants
total 8
drwxr-xr-x 2 root root 4096 Jan 29 17:27 ./
drwxr-xr-x 13 root root 4096 Jun 13 2017 ../
[...]
lrwxrwxrwx 1 root root 33 Jun 15 2016 nginx.service -> /lib/systemd/system/nginx.service
lrwxrwxrwx 1 root root 38 Nov 29 2016 php7.0-fpm.service -> /lib/systemd/system/php7.0-fpm.service
[...]

Ensuite c’est assez simple, il suffit d’ajouter la limitation de fichiers dans le service nginx ou fpm:

LimitNOFILE=30000

Voici le service complet pour php7.0-fpm:

[Unit]
Description=The PHP 7.0 FastCGI Process Manager
After=network.target

[Service]
Type=notify
PIDFile=/run/php/php7.0-fpm.pid
ExecStartPre=/usr/lib/php/php7.0-fpm-checkconf
ExecStart=/usr/sbin/php-fpm7.0 --nodaemonize --fpm-config /etc/php/7.0/fpm/php-fpm.conf
ExecReload=/usr/lib/php/php7.0-fpm-checkconf
ExecReload=/bin/kill -USR2 $MAINPID
LimitNOFILE=30000

[Install]
WantedBy=multi-user.target

idem pour la limitation dans une session ssh. Le /etc/security/limits.conf n’a pas d’effet, j’ai donc forcé la limitation en ajoutant directement un ulimit dans le /etc/bash.bashrc :

ulimit -n 30000

Attention ceci s’appliquera à tous les utilisateurs, assurez-vous que c’est acceptable dans votre cas d’utilisation.

Mémos et liens utiles pour améliorer les performances d’nginx et php-fpm

Faut-il ou non mettre un cache ?

Il faut se poser la question de la donnée reçue en réponse de la requête : est-ce que la donnée doit être rafraîchie à chaque requête ou non. Cette question s’applique aussi bien a des données dynamiques que statiques, car une donnée statique peut être mise à jour par un gestionnaire de configuration à la volée, il faut alors savoir quelle est la fréquence d’update ou de changement de version du fichier. Dans l’autre sens, une donnée dynamique peut très bien s’avérer statique sur un an, imaginons une page de contact en php, dont l’html généré ne change qu’une fois l’an. Bref du bon sens et une bonne connaissance des contenus est nécessaire pour paramétrer au mieux son cache et un copié/collé d’une config trouvée sur le web n’aidera pas forcément.

A un niveau extrême, sur des cas d’usage à très forte volumétrie, la création d’un micro-cache sur un stream dynamique (php ou autre) est a étudier pour bénéficier de certaine optimisation nginx sur le remplissage de la socket TCP.

Gérer les buffers d’entrée et de sortie

https://www.nginx.com/resources/admin-guide/reverse-proxy/

Gardez à l’esprit qu’on est sur du TCP, donc le MTU et la gestion du buffer réseau va impacter le tout. De ce fait nginx a mis en place des directives pour optimiser tout ça :

sendfile on;
tcp_nopush on;
tcp_nodelay on;

Voici une explication claire de ce qui se passe derrière ces directives :

https://thoughts.t37.net/optimisations-nginx-bien-comprendre-sendfile-tcp-nodelay-et-tcp-nopush-2ab3f33432ca

La référence nginx pour du cache

https://www.nginx.com/blog/nginx-caching-guide/

Erreurs classiques sur nginx

https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/

De ce fait utilisez plutôt une variable (directive set) dans une directive location afin d’éviter la directive if et utilisez la directive proxy_cache_bypass pour ouvrir des trous dans le proxy et ainsi ne pas inclure dans le cache des contenus temps réels.

L’option de faire un micro-cache dédié au contenu temps-réel peut aussi être une option afin de réduire la latence liée au remplissage du buffer réseau.

Du cache en RAM, pour réduire les accès disques

https://angristan.fr/cache-module-pagespeed-ram-tmpfs/

Tmpfs ou Ramfs

tmpfs est meilleur que ramfs car plus récent mais on peut retomber sur des accès disques car tmpfs peut repartir dans le swap.

https://www.jamescoyle.net/knowledge/951-the-difference-between-a-tmpfs-and-ramfs-ram-disk

Une configuration

https://serversforhackers.com/c/nginx-caching

Cette configuration est une bonne base pour comprendre les principes et voir la différence  entre un cache de fichiers statiques et un cache fastcgi. Il reste à ajouter un micro-cache en mémoire, customiser les tailles de buffers et supprimer les if.