Augmenter le nombre maximum de connexions tcp/ip sous linux

je suis en train de programmer un serveur et il semble que mon nombre de connexions soit limité puisque ma bande passante n'est pas saturée même quand j'ai mis le nombre de connexions à"illimité".

Comment puis-je augmenter ou éliminer un nombre maximum de connexions que ma boîte Linux Ubuntu peut ouvrir à la fois? L'OS limite-t-il cela, ou est-ce le routeur ou le FAI? Ou est-ce autre chose?

162
demandé sur Alvaro Fuentes 2009-01-04 10:35:46

4 réponses

nombre Maximum de connexions sont affectées par certaines limites à la fois du côté client et du côté serveur, bien qu'un peu différemment.

du côté du client: Augmenter la gamme de port ephermal, et diminuer le tcp_fin_timeout

Pour connaître les valeurs par défaut:

sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout

la plage de ports ephermal définit le nombre maximum de sockets sortants qu'un hôte peut créer à partir d'un IP particulier. adresse. Le fin_timeout définit le temps minimum pendant lequel ces sockets resteront dans l'état TIME_WAIT (inutilisable après avoir été utilisé une fois). Les valeurs par défaut habituelles du système sont:

  • net.ipv4.ip_local_port_range = 32768 61000
  • net.ipv4.tcp_fin_timeout = 60

cela signifie essentiellement que votre système ne peut garantir de façon constante plus de (61000 - 32768) / 60 = 470 prises par seconde. Si vous n'êtes pas satisfait de cela, vous pouvez commencer par augmenter le port_range . Fixer la portée à 15000 61000 est assez courant de nos jours. Vous pouvez encore augmenter la disponibilité en diminuant le fin_timeout . Supposons que vous faites les deux, vous devriez voir plus de 1500 connexions sortantes par seconde, plus facilement.

pour changer les valeurs :

sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30

ce qui précède ne doit pas être interprété comme les facteurs influant sur la capacité du système à effectuer des connexions sortantes par seconde. Mais plutôt ces les facteurs influent sur la capacité du système à gérer les connexions simultanées d'une manière durable pendant de longues périodes d'activité."

valeurs Sysctl par défaut sur une machine Linux typique pour tcp_tw_recycle & tcp_tw_reuse serait

net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0

ceux-ci ne permettent pas une connexion à partir d'une socket" utilisée "(en état d'attente) et forcent les sockets à durer le cycle complet time_wait . Je recommande le réglage:

sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1 

cela permet cycle rapide des sockets dans l'état time_wait et les réutiliser. Mais avant de faire ce changement, assurez-vous que cela n'entre pas en conflit avec les protocoles que vous utiliseriez pour l'application qui a besoin de ces sockets. Assurez-vous de lire post "faire face au temps D'attente TCP" de Vincent Bernat pour comprendre les implications. L'option net.ipv4.tcp_tw_recycle est assez problématique pour les serveurs faisant face au public car elle ne gère pas les connexions à partir de deux serveurs différents. ordinateurs derrière le même appareil NAT , qui est un problème difficile à détecter et à attendre de vous mordre. Notez que net.ipv4.tcp_tw_recycle a été supprimé de Linux 4.12.

du côté du serveur: La valeur net.core.somaxconn joue un rôle important. Il limite le nombre maximum de requêtes en attente à une socket listen. Si vous êtes sûr de la capacité de votre application serveur, passez de 128 par défaut à quelque chose comme 128 au 1024. Maintenant, vous pouvez profiter de cette augmentation en modifiant la variable Listen backlog dans l'appel listen de votre application, à un entier égal ou supérieur.

sysctl net.core.somaxconn=1024

txqueuelen paramètre de vos cartes ethernet ont également un rôle à jouer. Les valeurs par défaut sont 1000, donc passez à 5000 ou même plus si votre système peut le gérer.

ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local

augmente également les valeurs de net.core.netdev_max_backlog et net.ipv4.tcp_max_syn_backlog . Par défaut les valeurs sont respectivement de 1000 et 1024.

sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048

n'oubliez pas de démarrer à la fois vos applications côté client et côté serveur en augmentant les limites, dans l'interpréteur de commandes.

outre ce qui précède, une technique plus populaire utilisée par les programmeurs est de réduire le nombre d'appels tcp write . Ma propre préférence est d'utiliser un tampon dans lequel je pousse les données que je souhaite envoyer au client, et puis à des points appropriés j'écris les données sont tamponnées dans la socket réelle. Cette technique me permet d'utiliser de grands paquets de données, de réduire la fragmentation, de réduire l'utilisation de mon CPU à la fois dans le pays de l'utilisateur et au niveau du noyau.

304
répondu mdk 2018-09-26 13:37:24

il y a quelques variables pour définir le nombre maximum de connexions. Très probablement, vous êtes à court de numéros de dossier d'abord. Vérifiez ulimit-N. Après cela, il y a des paramètres dans /proc, mais ceux par défaut sont des dizaines de milliers.

plus important, on dirait que vous faites quelque chose de mal. Une seule connexion TCP devrait pouvoir utiliser toute la bande passante entre deux parties; si ce n'est pas le cas:

  • vérifiez si votre TCP la fenêtre de réglage est assez grand. Les valeurs par défaut de Linux sont bonnes pour tout sauf les liens inet vraiment rapides (des centaines de mbps) ou les liens satellites rapides. Quel Est votre produit de retard de bande passante*?
  • vérifier la perte de paquets en utilisant le ping avec les grands paquets ( ping -s 1472 ...)
  • Vérifiez la limitation de vitesse. Sur Linux, il est configuré avec tc
  • confirmer que la bande passante que vous pensez existe existe réellement en utilisant par exemple, iperf
  • confirmez que votre protocole est sain. Rappelez-vous le temps de latence.
  • S'il s'agit d'un Gigabit+ LAN, pouvez-vous utiliser des paquets jumbo? Êtes-vous?

J'ai peut-être mal compris. Peut-être que tu fais quelque chose comme Bittorrent, où tu as besoin de beaucoup de relations. Si c'est le cas, vous devez déterminer combien de connexions vous utilisez réellement (essayez netstat ou lsof ). Si ce nombre est important, vous pourriez:

  • ont beaucoup de bande passante, par exemple, 100mbps+. Dans ce cas, vous pourriez avoir besoin de monter le ulimit -n . Encore, ~1000 connexions (par défaut sur mon système), est assez peu.
  • ont des problèmes de réseau qui ralentissent vos connexions (par ex. perte de paquets)
  • ont quelque chose d'autre qui vous ralentit, par exemple, la bande passante IO, surtout si vous cherchez. Avez-vous coché iostat -x ?

aussi, si vous utilisez un routeur NAT de qualité grand public (Linksys, Netgear, DLink, etc.), méfiez-vous que vous pouvez dépasser ses capacités avec des milliers de connexions.

j'espère que cela donne un peu d'aide. Vous posez vraiment une question de réseau.

54
répondu derobert 2009-01-04 08:02:32

Pour améliorer la réponse donnée par derobert,

vous pouvez déterminer quelle est la limite de connexion de votre système d'exploitation en calculant nf_conntrack_max.

par exemple: cat / proc/sys/net/netfilter / nf_conntrack_max 151920920"

, Vous pouvez utiliser le script suivant pour compter le nombre de connexions tcp à une plage de ports tcp. Par défaut 1 et 65535.

cela confirmera si oui ou non vous maxez votre OS limite de connexion.

voici le script.

#!/bin/bash
OS=$(uname)

case "$OS" in
    'SunOS')
            AWK=/usr/bin/nawk
            ;;
    'Linux')
            AWK=/bin/awk
            ;;
    'AIX')
            AWK=/usr/bin/awk
            ;;
esac

netstat -an | $AWK -v start=1 -v end=65535 ' $NF ~ /TIME_WAIT|ESTABLISHED/ &&  !~ /127\.0\.0\.1/ {
    if ( ~ /\./)
            {sip=}
    else {sip=}

    if ( sip ~ /:/ )
            {d=2}
    else {d=5}

    split( sip, a, /:|\./ )

    if ( a[d] >= start && a[d] <= end ) {
            ++connections;
            }
    }
    END {print connections}'
14
répondu whitehat237 2012-10-12 18:36:35

au niveau de l'application, voici quelque chose qu'un développeur peut faire:

du côté du serveur:

  1. vérifiez si l'équilibrage de la charge(si vous avez) fonctionne correctement.

  2. Tour lent délais d'attente TCP en 503 Rapide réponse Immédiate, si vous équilibreur de charge fonctionne correctement, il devrait choisir la travail de ressources pour servir, et c'est mieux que de trainer là-bas avec des massages d'erreurs inattendus.

Eg: si vous utilisez node server, vous pouvez utiliser toobusy à partir de npm. Mise en œuvre quelque chose comme:

var toobusy = require('toobusy');
app.use(function(req, res, next) {
  if (toobusy()) res.send(503, "I'm busy right now, sorry.");
  else next();
});

pourquoi 503? Voici quelques bonnes idées pour la surcharge: http://ferd.ca/queues-don-t-fix-overload.html

nous pouvons aussi faire du travail côté client:

  1. groupez les appels par lots, réduisez le trafic et le nombre total de requêtes B/W client et serveur.

  2. essayez de construire une couche intermédiaire de cache pour gérer les requêtes inutiles.

10
répondu Kev 2014-11-19 21:26:44