Ngnix est connue pour son load balancing haute performance et également pour sont cache statique et sa dérivabilité de contenus statiques. Nous allons voir comment optimiser les capacités de nginx.

Les deux facteurs qui font avoir le plus d’influence sur les performance c’est l’adaptation du nombre de worker (processus) et du nombre de conexions maximum par worker. il suffit de l’indiquer dans le fichier de config /etc/nginx/nginx.conf

Worker_processes : 

Définir un seul worker suffit amplement dans le cas d’un serveur a faible trafic, hébergent également une base de données et une application web. on va dans ce cas définir

worker_processes 1;

Cela minimise l’emprunte de charge de ngnix, pas besoin de plus.

Dans le cas d’un traffic a plus forte charge, la pratique courante est d’exécuter un worker par coeur de votre CPU.

La commande suivante va vous permettre de connaitre le nombre de CPU sur votre machine :

grep processor /proc/cpuinfo | wc -l

Note la valeur “Auto” permet de définir ça automatiquement

worker_processes auto;

Worker_Connections : 

il faut se souvenir que le nombre de client qui peuvent être servi est le multiple du nombre de connection par le nombre de worker. Mécaniquement plus on a de coeur plus en théorie on toucher de client en même temps 😉 tout ceci etant pondéré par l’action du keepalive.

Sur une petite machine avec 512MB de RAM et un seul coeur la valeur raisonnable de départ est de 512. mais vous pouvez aller jusqu’a la limite des capacité réel que l’on trouve avec la commade suivante.

ulimit -n

Pour conclure, avec un serveur de 4 coeurs et 1024 connecxions max, on peut atteindre 4096 connexions simultané.

 

keepalive : 

le keepalive est une mécanique de maintient de la connexion tcp, pour eviter au client de lancer une conexion Tcp pour chaque requetes, un keepalive très long optimise l’expérience utilisateur au détriment de la disponibilité du serveur, car n’oublions pas que le nombre de connexions a un limite.

tcpka.png

  • Keepalivee_timeout : délai maximum en secondes entre chaque requêtes du maintient d’une connexion TCP .
  • Keepalive_requests : nombre maximum de requêtes pour une connexion TCP.
keepalive_timeout 15; 
keepalive_requests 10000;

 

Static Asset Serving :

Normalement les assets sont toutes statiques, images, Javascripts, CSS, etc… Nginx peut mettre en cache ces fichiers pour une période limité. on peut definir un nombre max de 1000 fichiers a mettre en cache pour 30 secondes , exclure tous ceux qui n’ont pas été demandé depuis 20 secondes et seulement pour les fichier demandé plus de 5 fois. ce qui nous donne la configuration suivante

open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 5;
open_file_cache_errors off;

Les valeurs peuvent êtres augmenter de manière significative si le contenu change rarement.

il est possible aussi de définir un cache pour un chemin ou des fichiers spécifiques

location ~* .(woff|eot|ttf|svg|mp4|webm|jpg|jpeg|png|gif|ico|css|js)$ {
    expires 365d;
}

 

Gzip compression :

Pour les contenus non binaires et donc de type texte, il es conseillé d’utiliser la compression pour renvoyer les données au clients. la plus part des navigateur l’accepte

Voici un exemple qui parle de lui même

gzip on;
gzip_min_length 1000;

gzip_types: text/html application/x-javascript text/css application/javascript text/javascript text/plain text/xml application/json application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xml font/eot font/opentype font/otf image/svg+xml image/vnd.microsoft.icon;

gzip_disable "MSIE [1-6]\.";

 

TimeOuts :

Les timesouts vont augmenter de manière conséquente les performance de nginx

  • client_body_timeout : c’est la durée maximum d’attente de nginx pour recevoir le corp de la requete http. dans la limite le serveur va envoyé une erreur 408 Request time out.
  • client_body_timeout : est la durée maximum d’attente de nginx pour recevoir le corp de la requete http.
  • sent_timeout : delai maximum de lecture de la reponse du serveur.

Les timesout sont des gardes fou, il permet d’optimiser la libération des connexions, encore une fois en fonction des cas d’usage un bon tuning permet d’améliorer les performances.

Buffers:

On va plus loin avec la configuration du buffer de nginix, c’est pas un secret plus il y a de buffer moins il y a aura d’I/O ( ecriture disque ), donc il sagit d’optimiser le performance sans tomber dans les limites de la ram. il faut a partir d’ici s’adapter au service qui est derrière nginx car c’est lui qui va imposer le profil du buffer.

  • client_body_buffer_size : limite du buffer pour les requetes POST envoyé a nginx
  • client_header_buffer_size: limite pour les entêtes de requetes, 1K est generalement suffisant sans être trop gros.
  • client_max_body_size : c’est la taille maximum d’une requete authorisé par le client, en cas de dépassement nginx renvoi une erreur “413 error or Request Entity Too Large.”
  • large_client_header_buffers : c’est le nombre maximum et la taille max des buffers pour les entêtes des clients.

Exemple de configuration courante :

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

On note qu’il n’est pas possible de stoker dans le buffer des POST supérieur a 10K, si cela reste une exception, ça ne pose pas de problème.

Si une requête POST dépasse les 8Mb, la c’est l’erreur assuré ( a voir concernant par exemple l’upload de fichier ) dans le cas du page web avec de simple formulaire sans upload de fichier, il est vraiment conseillé de baisser la valeur 10k, pour éviter des actions mal intentioné.

Ce n’est pas une science exacte, mais un tuning qui va dépendre des capacités du serveur, du nombre de connexion simultané définies, de RAM disponible et de l’application derrière nginx qui va définir le cas d’usage. De ce coté la des metrics sont indispensables pour optimiser avec précision les buffers.

Connection Queue:

il y a des directives dans le fichier /etc/sysctl.conf  qui permet de changer la taille de la queue pour les connexions et les buffers au niveau de l’os.

net.core.somaxconn = 65536
net.ipv4.tcp_max_tw_buckets = 1440000

Une méthode empirique consiste a incrémenter progressivement les valeurs tant qu’il y a pas d’erreur visible dans le log du kernel !

 

Plus d’information sur l’optimisation de nginix au niveau du systeme

 

 

Advertisements