Valeur optimale pour Nginx worker_connections

25

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 mandatés, entre autres), pas seulement les connexions avec les clients. Une autre considération est que le nombre réel de connexions simultanées ne peut pas dépasser la limite actuelle du nombre maximal de fichiers ouverts ". J'ai quelques questions à ce sujet:

  1. Quelle devrait être la valeur optimale ou recommandée pour cela?
  2. Quels sont les inconvénients de l'utilisation d'un nombre élevé de connexions de travail?
Aarti
la source
+1, bonne question!
cnst

Réponses:

31

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.

worker_process

Un paramètre connexe, expliquons-le pendant que nous sommes sur le sujet.

nginx comme équilibreur de charge:

  • 1 travailleur pour l'équilibrage de charge HTTP.
  • 1 travailleur par cœur pour l'équilibrage de charge HTTPS.

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.

connexions_ouvriers

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:

  • ulimits est 1k max de fichiers ouverts par processus sur linux (1k soft, 4k hard sur certaines distributions)
  • les limites de systemd sont à peu près les mêmes que les ulimits.
  • nginx par défaut est 512 connexions par travailleur.
  • Il pourrait y en avoir plus: SELinux, sysctl, supervisord (chaque version de distribution + est légèrement différente)

1k connexions_travailleurs

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.

10k connexions_travailleurs

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.

Plus de 10k

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) davantage nécessiteront un réglage et une analyse comparative spéciaux.

Scénario spécial: utilisation avancée

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 de bons messages d'erreur et une bonne gestion.

Parfois, les serveurs d'arrière-plan fonctionnent bien et bien, mais 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é.

user5994461
la source
J'aime la réponse, mais pour faire une supposition vraiment éclairée sur la hauteur à laquelle cela doit être réglé, il semble que nous devions savoir à peu près combien de RAM une connexion prend (par exemple pour enregistrer un fichier statique normal avec sendfile) afin que nous puissions multiplier jusqu'à calculer combien de RAM serait nécessaire pour maintenir un nombre donné de worker_connections.
nh2
1
Vous pouvez faire jusqu'à 10k sans trop de réglage. Les tampons de connexion sont définis dans les sysctlparamètres.
user5994461
10

ulimit -a vous indiquera combien de fichiers ouverts votre système autorise à utiliser un processus.

Définit également net.ipv4.ip_local_port_rangela plage totale de sockets à activer par IP.

Donc, vous worker_connectionsne pouvez pas être plus que n'importe lequel de ces éléments, ou vos connexions clientes feront la queue jusqu'à 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_timeoutet d'autres délais d'expiration liés au tcp du noyau pour essayer de changer rapidement l'état des sockets. Une autre chose à noter est que chaque socket alloue de la mémoire à la pile de mémoire TCP, vous pouvez également définir certaines limites de la pile de mémoire TCP à l'aide sysctl, vous pouvez mettre plus de pression dans la RAM tant que vous avez un processeur 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 un réglage 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!

Marcel
la source
veuillez corriger la commande pour ulimit pas ulimits
Ali.MD
La note net.ipv4.ip_local_port_rangen'est pertinente que pour les connexions sortantes , pas pour les connexions entrantes (comme c'est généralement le cas avec nginx sur les ports 80 et 443, par exemple); voir ici .
nh2
@ nh2 mais si l'on utilise nginx comme proxy inverse, il y a au moins 2 sockets ouverts par connexion client, et il importe alors combien de ports locaux le noyau peut autoriser les sockets à se lier.
Marcel
Oui c'est correct.
nh2
0

Le dimensionnement approprié peut être découvert par le biais de tests, car il varie 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

Sachin Gargya
la source
En fait, avec le proxy inverse: max_clients = (worker_processes * worker_connections) / (X * 2) où X est cependant le nombre de connexions simultanées que ces clients vous établissent. En outre, les structures de connexion sont utilisées pour les sockets d'écoute, les sockets de contrôle interne entre les processus nginx et pour les connexions en amont. Donc, ce max clients = worker_processes * worker_connections ne fonctionnera pas car nous ne savons pas que de nombreuses connexions sont utilisées dans les sockets de contrôle interne.
Aarti
0

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 aussi avec les serveurs en amont ), gaspillent efficacement vos ressources (même si nginx est très efficace, ce qui est le cas), et ne sont pas nécessaires 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

cnst
la source
0

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 travail ne peuvent pas être supérieures à celles-ci, ou vos connexions clientes feront la file d'attente jusqu'à ce que net.core.netdev_max_backlog - la taille totale de la file d'attente TCP".

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. La définition de max_connection sur une valeur très élevée peut se retourner contre vous car les ulimits seront un facteur limitant.

Cryptophobie
la source
1
C'est faux en fait. La limite logicielle sur Linux de bureau est de 1 Ko, mais elle n'empêche pas les processus d'utiliser plus que cela s'ils le demandent, jusqu'à la limite matérielle (32 Ko ou plus). nginx augmentera automatiquement l'ulimit s'il max_connectionsest supérieur à la limite logicielle par défaut.
user5994461