Le nombre maximal de connexions est influencé par certaines limites, tant du côté client que du côté serveur, mais de manière un peu différente.
Du côté du client : Augmentez la portée du port éphémère, et diminuez 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 port éphémère définit le nombre maximum de sockets sortants qu'un hôte peut créer à partir d'une adresse I.P. particulière. L'adresse fin_timeout
définit le temps minimum pendant lequel ces sockets resteront en 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 pas garantir de manière constante plus que (61000 - 32768) / 60 = 470
sockets par seconde. Si vous n'êtes pas satisfait de ce résultat, vous pouvez commencer par augmenter le nombre de sockets par seconde. port_range
. Réglage de la gamme sur 15000 61000
est assez courante de nos jours. Vous pouvez encore augmenter la disponibilité en diminuant le nombre d'heures d'utilisation. fin_timeout
. Supposons que vous fassiez les deux, vous devriez voir plus de 1500 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
Les données ci-dessus ne doivent pas être interprétées comme les facteurs ayant un impact sur la capacité du système à établir des connexions sortantes par seconde. Mais plutôt ces facteurs affectent la capacité du système à gérer des connexions simultanées de manière durable pendant de grandes périodes d'"activité".
Valeurs par défaut de Sysctl sur une boîte 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 de se connecter à partir d'une socket "utilisée" (en état d'attente) et forcent les sockets à durer toute la durée de l'opération. time_wait
cycle. Je recommande de le régler :
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
Cela permet un cycle rapide des prises dans time_wait
et de les réutiliser. Mais avant d'effectuer 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 le post "Faire face au TCP TIME-WAIT" de Vincent Bernat pour comprendre les implications. Le site net.ipv4.tcp_tw_recycle
est assez problématique pour les serveurs ouverts au public, car elle ne permet pas de gérer les connexions provenant de deux ordinateurs différents situés derrière le même dispositif NAT. Il s'agit d'un problème difficile à détecter qui ne demande qu'à être résolu. Notez que net.ipv4.tcp_tw_recycle
a été supprimé de Linux 4.12.
Du côté du serveur : Le site net.core.somaxconn
a un rôle important. Elle limite le nombre maximal de requêtes mises en file d'attente sur un socket d'écoute. Si vous êtes sûr des capacités de votre application serveur, augmentez la valeur par défaut de 128 à quelque chose comme 128 à 1024. Vous pouvez maintenant tirer parti de cette augmentation en modifiant la variable listen backlog dans l'appel listen de votre application, avec un nombre 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 de 1000, alors augmentez-les à 5000 ou même plus si votre système peut le supporter.
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
y 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
Maintenant, n'oubliez pas de démarrer vos applications côté client et côté serveur en augmentant les ulimts FD, dans le shell.
En plus de ce qui précède, une autre technique populaire utilisée par les programmeurs consiste à réduire le nombre d'éléments suivants tcp écrire appels. Ma préférence va à l'utilisation d'une mémoire tampon dans laquelle je pousse les données que je souhaite envoyer au client, puis, aux endroits appropriés, j'écris les données mises en mémoire tampon 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 du CPU tant au niveau de l'utilisateur qu'au niveau du noyau.