web-dev-qa-db-fra.com

Y a-t-il une limite sur le nombre de connexions TCP / IP entre les machines sous Linux?

J'ai un programme très simple écrit en 5 min qui ouvre un socket de serveur et boucle la demande et imprime à l'écran les octets qui lui sont envoyés.

J'ai ensuite essayé de comparer le nombre de connexions que je peux utiliser avec pour essayer de savoir combien d'utilisateurs simultanés je peux prendre en charge avec ce programme.

Sur une autre machine (où le réseau entre eux n'est pas saturé) j'ai créé un programme simple qui entre en boucle et se connecte à la machine serveur et envoie les octets "hello world".

Lorsque la boucle est 1000-3000, le client termine avec toutes les demandes envoyées. Lorsque la boucle dépasse 5000, elle commence à avoir des temps morts après avoir terminé le premier nombre X de demandes. Pourquoi est-ce? Je me suis assuré de fermer ma prise dans la boucle.

Pouvez-vous seulement créer autant de connexions dans un certain laps de temps?

Cette limite s'applique-t-elle uniquement entre les mêmes machines et je n'ai pas à m'en soucier en production où plus de 5000 requêtes proviennent toutes de machines différentes?

24
erotsppa

Il y a une limite, oui. Voir ulimit.

Vous devez également prendre en compte le TIMED_WAIT Etat. Une fois qu'un socket TCP socket est fermé (par défaut) le port reste occupé dans TIMED_WAIT état pendant 2 minutes. Cette valeur est réglable. Cela vous "manquera également de prises" même si elles sont fermées.

Exécutez netstat pour voir le TIMED_WAIT des trucs en action.

P.S. La raison pour TIMED_WAIT est pour gérer le cas des paquets arrivant après la fermeture du socket. Cela peut se produire parce que les paquets sont retardés ou que l'autre côté ne sait tout simplement pas que le socket est encore fermé. Cela permet au système d'exploitation de supprimer silencieusement ces paquets sans risque "d'infecter" une connexion de socket différente et sans rapport.

26
Jason Cohen

Lorsque vous recherchez les performances maximales, vous rencontrez de nombreux problèmes et goulots d'étranglement potentiels. Exécuter un simple test du monde bonjour ne va pas nécessairement les trouver tous.

Les limitations possibles incluent:

  • Limitations des sockets du noyau: regardez dans /proc/sys/net pour beaucoup de réglages du noyau ..
  • limites du processus: consultez ulimit comme d'autres l'ont indiqué ici
  • au fur et à mesure que votre application se complexifie, il se peut qu'elle n'ait pas assez de puissance CPU pour suivre le nombre de connexions entrant. Utilisez top pour voir si votre CPU est au maximum
  • le nombre de fils? Je n'ai pas d'expérience avec le filetage, mais cela peut entrer en jeu conjointement avec les éléments précédents.
8
DGM

Votre serveur est-il monothread? Si oui, quelle fonction de polling/multiplexage utilisez-vous?

L'utilisation de select () ne fonctionne pas au-delà de la limite maximale de descripteur de fichier codée en dur définie au moment de la compilation, qui est sans espoir (normalement 256, ou quelques autres).

poll () est mieux, mais vous vous retrouverez avec le problème d'évolutivité avec un grand nombre de FD repeupler l'ensemble à chaque fois dans la boucle.

epoll () devrait bien fonctionner jusqu'à une autre limite que vous atteignez.

Les connexions 10k devraient être assez faciles à réaliser. Utilisez un noyau 2.6 récent (ish).

Combien de machines client avez-vous utilisées? Êtes-vous sûr de ne pas avoir atteint de limite côté client?

2
MarkR

La réponse rapide est 2 ^ 16 TCP ports, 64K.

Le problème des limites imposées par le système est un problème de configuration, déjà évoqué dans les commentaires précédents.

Les implications internes de TCP n'est pas si claire (pour moi). Chaque port nécessite de la mémoire pour son instanciation, va sur une liste et a besoin de tampons réseau pour les données en transit.

Étant donné 64K TCP, la surcharge des instances des ports peut être un problème sur un noyau 32 bits, mais pas sur un noyau 64 bits (correction ici volontiers acceptée). Le processus de recherche avec 64K Les sessions peuvent ralentir un peu les choses et chaque paquet atteint les files d'attente du minuteur, ce qui peut également être problématique.Le stockage des données en transit peut théoriquement gonfler jusqu'aux ports de taille de fenêtre (peut-être 8 Go).

Le problème avec la vitesse de connexion (mentionné ci-dessus) est probablement ce que vous voyez. TCP prend généralement du temps pour faire les choses. Cependant, ce n'est pas nécessaire. A TCP se connecter, effectuer des transactions et se déconnecter peut se faire très efficacement (vérifiez les TCP sont créées et fermées).

Il y a des systèmes qui passent des dizaines de gigabits par seconde, donc la mise à l'échelle du niveau de paquet devrait être OK.

Il y a des machines avec beaucoup de mémoire physique, donc ça semble OK.

Les performances du système, si elles sont soigneusement configurées, devraient être correctes.

Le côté serveur des choses devrait évoluer de la même manière.

Je serais préoccupé par des choses comme la bande passante mémoire.

Envisagez une expérience où vous vous connectez à l'hôte local 10 000 fois. Tapez ensuite un caractère. La pile entière à travers l'espace utilisateur serait engagée sur chaque personnage. L'empreinte active dépasserait probablement la taille du cache de données. Traverser beaucoup de mémoire peut stresser le système VM. Le coût des changements de contexte pourrait approcher une seconde!

Ceci est discuté dans une variété d'autres threads: https://serverfault.com/questions/69524/im-designing-a-system-to-handle-10000-tcp-connections-per-second-what- problèmes

2
Trivet

Vous voudrez peut-être consulter /etc/security/limits.conf

1
Ian

Oui, la limite est fixée par le noyau; consultez ce fil sur Stack Overflow pour plus de détails: augmentation du nombre maximum de connexions tcp/ip sous linux

1
Don Werve