Nginx worker_connections
"définit le nombre maximal de connexions simultanées pouvant être ouvertes par un processus de travail. Ce nombre inclut toutes les connexions (par exemple, les connexions avec des serveurs mandataires, entre autres), pas seulement les connexions avec les clients. Une autre considération est que la valeur réelle le nombre de connexions simultanées ne peut pas dépasser la limite actuelle du nombre maximal de fichiers ouverts ". J'ai quelques questions à ce sujet:
Prenons l'approche pragmatique.
Toutes ces limites sont des choses qui ont été codées en dur et conçues au cours du siècle dernier lorsque le matériel était lent et coûteux. Nous sommes en 2016 maintenant, un grille-pain Wall-Mart moyen peut traiter plus de demandes que les valeurs par défaut.
Les paramètres par défaut sont en fait dangereux. Avoir des centaines d'utilisateurs sur un site Web n'a rien d'impressionnant.
Un paramètre connexe, expliquons-le pendant que nous sommes sur le sujet.
nginx comme équilibreur de charge:
nginx en tant que serveurs web:
Celui-ci est délicat.
Certaines applications/frameworks/middleware (par exemple php-fpm) sont exécutés en dehors de nginx. Dans ce cas, 1 travailleur nginx suffit, car c'est généralement l'application externe qui effectue le traitement lourd et consomme les ressources.
De plus, certaines applications/frameworks/middleware ne peuvent traiter qu'une seule demande à la fois et cela se retourne pour les surcharger.
De manière générale, 1 travailleur est toujours une valeur sûre.
Sinon, vous pouvez mettre un travailleur par cœur si vous savez ce que vous faites. Je considérerais cette route comme une optimisation et je conseillerais une analyse comparative et des tests appropriés.
Le nombre total de connexions est worker_process * worker_connections
. La moitié en mode équilibreur de charge.
Nous arrivons maintenant à la partie grille-pain. Il existe de nombreuses limites du système sérieusement sous-estimées:
Le défaut par défaut est de mettre 1k partout.
Il est suffisamment élevé pour être plus que la plupart des sites internes et inconnus ne rencontreront jamais. Il est suffisamment bas pour ne toucher aucune autre limite du système.
Il est très courant d'avoir des milliers de clients, en particulier pour un site Web public. J'ai arrêté de compter le nombre de sites Web que j'ai vus en raison des faibles valeurs par défaut.
Le minimum acceptable pour la production est de 10k. Les limites du système associé doivent être augmentées pour le permettre.
Il n'y a pas de limite trop élevée (une limite n'a tout simplement aucun effet s'il n'y a pas d'utilisateurs). Cependant, une limite trop basse est une chose très réelle qui se traduit par des utilisateurs rejetés et un site mort.
10k est agréable et facile.
Nous pourrions fixer des limites arbitraires de 1000kk (ce n'est qu'une limite après tout) mais cela n'a pas beaucoup de sens pratique, nous n'obtenons jamais ce trafic et ne pouvons pas le prendre de toute façon.
Restons-en à 10k comme paramètre raisonnable. Les services qui vont (et peuvent vraiment faire) plus nécessiteront un réglage et un benchmarking spéciaux.
Parfois, nous savons que le serveur n'a pas beaucoup de ressources et nous nous attendons à des pics que nous ne pouvons pas faire grand-chose. Nous préférons refuser les utilisateurs que d'essayer. Dans ce cas, définissez une limite de connexion raisonnable et configurez les messages d'erreur et la gestion de Nice.
Parfois, les serveurs dorsaux fonctionnent bien et bien mais seulement jusqu'à une certaine charge , rien de plus et tout va vite au sud. Nous préférons ralentir plutôt que de faire planter les serveurs. Dans ce cas, configurez la mise en file d'attente avec des limites strictes, laissez nginx mettre en mémoire tampon toute la chaleur pendant que les demandes sont drainées à un rythme limité.
ulimit -a
vous indiquera combien de fichiers ouverts votre système autorise à utiliser un processus.
Aussi, net.ipv4.ip_local_port_range
définit la plage totale de sockets à activer par IP.
Alors, votre worker_connections
ne peut pas dépasser ce nombre, ou vos connexions clientes seront mises en file d'attente jusqu'à ce que net.core.netdev_max_backlog
- la taille totale de la file d'attente TCP.
Gardez à l'esprit que si vous utilisez nginx comme proxy inverse, cela utilise deux sockets par connexion. Vous voudrez peut-être jouer un peu avec net.ipv4.tcp_fin_timeout
et d'autres délais d'attente liés au tcp du noyau pour essayer de changer rapidement l'état des sockets. Une autre chose à noter est que chaque socket alloue la mémoire de la pile de mémoire TCP, vous pouvez également définir certaines limites de la pile de mémoire TCP en utilisant sysctl
, vous pouvez mettre plus de pression dans le RAM tant que vous avez le CPU et suffisamment de gestionnaires de fichiers.
Pour info, il est possible, avec suffisamment de ressources informatiques, d'avoir un serveur avec environ 32 Go de RAM et des interfaces réseau virtuelles pour gérer des connexions simultanées de 1MM avec quelques réglages du noyau en utilisant sysctl. Lors de mes tests lorsque j'ai traité plus de 1MM et envoyé une charge utile d'environ 700Bytes, le serveur prenait environ 10 secondes pour mettre à jour environ 1,2MM de clients simultanés. La prochaine étape consistait à augmenter la bande passante du réseau en liant des cartes réseau supplémentaires et en abandonnant les cartes réseau virtuelles. Il est possible de réaliser une communication pseudo en temps quasi réel avec plus de 1,2 million de clients, compte tenu de la charge utile, de la bande passante et du temps raisonnable pour mettre à jour tous les clients.
Bon réglage!
La réponse de Marcel a vraiment besoin d'être votée! Si ulimits est défini sur une valeur par défaut d'environ 1k, max_connections doit être défini autour de la même valeur, sinon il n'y a aucun avantage à définir max_connections sur 10k.
Vous obtiendrez la demande en file d'attente et les sockets fermés sur nginx si "vos connexions de travailleurs ne peuvent pas être supérieures à celles-ci, ou vos connexions clientes seront en file d'attente jusqu'à ce que net.core.netdev_max_backlog - la taille totale du TCP queue."
Un seul processus peut s'ouvrir ainsi que la connexion comme le permettent les ulimits. num_workers * max_connections est la formule mais les connexions max et ulimits en dehors de l'équilibreur de charge/proxy doivent être prises en compte pour des valeurs raisonnables. Définir max_connection sur une valeur très élevée peut se retourner contre vous car les ulimits seront un facteur limitant.
Le dimensionnement approprié peut être découvert grâce aux tests, car il est variable en fonction du type de trafic géré par Nginx.
Théoriquement, nginx peut gérer: max clients = worker_processes * worker_connections (* = multiply) et worker_processes = nombre de processeurs
Pour connaître les processeurs, utilisez: grep processor/proc/cpuinfo | wc -l
La définition de limites inférieures peut être utile lorsque vous êtes limité par les ressources. Certaines connexions, par exemple, les connexions persistantes (non seulement avec les clients, mais avec les serveurs en amont , aussi), gaspillent efficacement vos ressources (même si nginx est très efficace, ce qui est le cas) et ne sont pas requis pour le bon fonctionnement d'un serveur à usage général, ce qui signifie qu'ils peuvent être supprimés en toute sécurité pour rendre plus de ressources disponibles pour le reste de l'opération.
Avoir une limite de ressources inférieure indiquerait donc à nginx que vous pourriez être à court de ressources physiques, et celles disponibles devraient être allouées à de nouvelles connexions, plutôt que de servir les connexions persistantes au ralenti au détriment des nouvelles connexions ayant du mal à être établies pour répondre aux besoins les plus pressants.
Quelle est la valeur recommandée? C'est la valeur par défaut.
Les valeurs par défaut sont toutes documentées dans la documentation:
Par défaut: worker_connections 512;
Et peut être confirmé au niveau du code source à event/ngx_event.c
, aussi
13 # définir DEFAULT_CONNECTIONS 512