Le nombre maximum de connexions est affecté par certaines limites à la fois côté client et côté serveur, quoique un peu différemment.
Côté client:
augmentez la plage de ports sphériques et diminuez latcp_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 éphermaux définit le nombre maximal de sockets sortants qu'un hôte peut créer à partir d'une adresse IP particulière. Le fin_timeout
définit la durée minimale pendant laquelle ces sockets resteront en TIME_WAIT
état (inutilisables après avoir été utilisées une fois). Les valeurs par défaut du système habituelles sont:
net.ipv4.ip_local_port_range = 32768 61000
net.ipv4.tcp_fin_timeout = 60
Cela signifie essentiellement que votre système ne peut pas toujours garantir plus de (61000 - 32768) / 60 = 470
sockets par seconde. Si vous n'êtes pas satisfait de cela, vous pouvez commencer par augmenter le port_range
. Régler la plage sur 15000 61000
est assez courant de nos jours. Vous pouvez augmenter encore la disponibilité en diminuant le fin_timeout
. Supposons que vous fassiez les deux, vous devriez voir plus de 1 500 connexions sortantes par seconde, plus facilement.
Pour modifier 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 affectant la capacité du système à établir des connexions sortantes par seconde. Mais ces facteurs affectent plutôt la capacité du système à gérer les connexions simultanées de manière durable pendant de longues périodes «d'activité».
Les valeurs par défaut de Sysctl sur une boîte Linux typique pour tcp_tw_recycle
& tcp_tw_reuse
seraient
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0
Celles-ci n'autorisent pas une connexion à partir d'un socket "utilisé" (en attente) et forcent les sockets à durer le time_wait
cycle complet . Je recommande de régler:
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
Cela permet un cycle rapide des sockets en time_wait
état et de les réutiliser. Mais avant d'effectuer cette modification, 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 le post "Coping with the TCP TIME-WAIT" de Vincent Bernat pour comprendre les implications. L' net.ipv4.tcp_tw_recycle
option est assez problématique pour les serveurs publics car elle ne gère pas les connexions de deux ordinateurs différents derrière le même périphérique NAT , ce qui est difficile à détecter et à attendre pour vous mordre. Notez que cela net.ipv4.tcp_tw_recycle
a été supprimé de Linux 4.12.
Côté serveur:
la net.core.somaxconn
valeur a un rôle important. Il limite le nombre maximal de requêtes mises en file d'attente sur un socket d'écoute. Si vous êtes sûr de la capacité de votre application serveur, augmentez-la de 128 par défaut à quelque chose comme 128 à 1024. Vous pouvez maintenant profiter de cette augmentation en modifiant la variable d'écoute de backlog dans l'appel d'écoute de votre application, à un entier égal ou supérieur.
sysctl net.core.somaxconn=1024
txqueuelen
Les paramètres de vos cartes Ethernet ont également un rôle à jouer. Les valeurs par défaut sont 1000, alors augmentez-les jusqu'à 5000 ou même plus si votre système peut les gérer.
ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local
De même, augmentez les valeurs de net.core.netdev_max_backlog
et net.ipv4.tcp_max_syn_backlog
. Leurs valeurs par défaut sont respectivement 1000 et 1024.
sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048
N'oubliez pas de démarrer vos applications côté client et côté serveur en augmentant les ulimts FD, dans le shell.
Outre la technique ci-dessus, la plus utilisée par les programmeurs consiste à réduire le nombre d' appels d' écriture TCP . Ma propre préférence est d'utiliser un tampon dans lequel je pousse les données que je souhaite envoyer au client, puis aux points appropriés j'écris les données tamponnées dans le socket réel. Cette technique me permet d'utiliser de gros paquets de données, de réduire la fragmentation, de réduire l'utilisation de mon processeur à la fois dans le pays utilisateur et au niveau du noyau.