105 votes

Qu'est-ce qui limite le nombre maximal de connexions sur un serveur Linux ?

Quel paramètre du noyau ou autres réglages contrôlent le nombre maximum de sockets TCP qui peuvent être ouverts sur un serveur Linux ? Quels sont les inconvénients de l'autorisation d'un plus grand nombre de connexions ?

J'ai remarqué en testant la charge d'un serveur Apache avec ab qu'il est assez facile de maximiser le nombre de connexions ouvertes sur le serveur. Si vous n'utilisez pas l'option -k d'ab, qui permet la réutilisation des connexions, et que vous lui demandez d'envoyer plus de 10 000 requêtes, Apache répond aux quelque 11 000 premières requêtes, puis s'arrête pendant 60 secondes. Un coup d'oeil à la sortie de netstat montre 11 000 connexions dans l'état TIME_WAIT. Apparemment, c'est normal. Les connexions sont maintenues ouvertes par défaut pendant 60 secondes, même après que le client en ait fini avec elles pour Raisons de la fiabilité du TCP .

Il semble que ce soit un moyen facile de détraquer un serveur et je me demande quels sont les réglages et les précautions habituels pour cela.

Voici le résultat de mon test :

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

Voici la commande netstat que j'exécute pendant le test :

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab

76voto

Ian Nelson Points 20020

J'ai finalement trouvé le paramètre qui limitait vraiment le nombre de connexions : net.ipv4.netfilter.ip_conntrack_max . Cette valeur a été fixée à 11 776 et quelle que soit la valeur que je lui donne, c'est le nombre de requêtes que je peux traiter dans mon test avant de devoir attendre. tcp_fin_timeout secondes pour que d'autres connexions soient disponibles. Le site conntrack est ce que le noyau utilise pour suivre l'état des connexions. Une fois qu'elle est pleine, le noyau commence à abandonner des paquets et l'affiche dans le journal :

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

L'étape suivante a consisté à faire en sorte que le noyau recycle toutes les connexions dans le fichier TIME_WAIT plutôt que de laisser tomber les paquets. J'ai pu faire en sorte que cela se produise soit en activant tcp_tw_recycle ou en augmentant ip_conntrack_max doit être plus grand que le nombre de ports locaux mis à disposition pour des connexions par ip_local_port_range . Je suppose qu'une fois que le noyau n'a plus de ports locaux, il commence à recycler les connexions. Cela utilise plus de mémoire pour suivre les connexions mais cela semble être la meilleure solution que d'activer la fonction tcp_tw_recycle puisque les docs impliquent que c'est dangereux.

Avec cette configuration, je peux faire tourner ab toute la journée et ne jamais manquer de connexions :

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

Le site tcp_max_orphans Le réglage n'a eu aucun effet sur mes tests et je ne sais pas pourquoi. Je pensais que cela fermerait les connexions dans TIME_WAIT a déclaré une fois qu'il y en avait 8192, mais il ne le fait pas pour moi.

4 votes

Où devons-nous configurer ces paramètres ?

3 votes

@Codevalley Cela peut dépendre du système, mais sur Ubuntu Server, ils vont dans /etc/sysctl.conf.

25voto

Jeff Thomas Points 183

Vous devriez vraiment examiner ce que le système de fichiers /proc a à vous offrir à cet égard.

Sur cette dernière page, vous trouverez peut-être les éléments suivants qui vous intéressent :

  • /proc/sys/net/ipv4/tcp_max_orphans qui contrôle le nombre maximum de sockets détenus par le système. no attaché à quelque chose. Augmenter cette valeur peut consommer jusqu'à 64 koctets de mémoire non remplaçable. par prise orpheline .
  • /proc/sys/net/ipv4/tcp_orphan_retries qui contrôle le nombre de tentatives avant qu'un socket ne soit orphelin et fermé. Il y a une note spécifique sur cette page concernant les serveurs web qui vous intéresse directement...

1 votes

Tcp_max_orphans est intéressant mais il semble qu'il ne fonctionne pas. Lorsque j'essaie de mesurer les sockets orphelins pendant mon test, j'en vois 11 651 alors que tcp_max_orphans est de 8 092. # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 11651 tcp 0 0 localhost:www TIME_WAIT -

0 votes

Regardez le paramètre tcp_orphan_retries - l'idée étant que les sockets sont "vidés" plus rapidement...

0 votes

La suggestion de @Jauder Ho + tcp_orphan_retries semble être une victoire potentielle pour votre situation.

4voto

Kyle Brandt Points 81077

Je ne pense pas qu'il y ait un tunable pour régler cela directement. Cela tombe dans la catégorie des réglages TCP/IP. Pour savoir ce que vous pouvez régler, essayez 'man 7 tcp'. Le sysctl ('man 8 sysctl') est utilisé pour définir ces paramètres. sysctl -a | grep tcp' vous montrera la plupart des paramètres que vous pouvez régler, mais je ne suis pas sûr qu'il les montrera tous. De plus, à moins que cela ait changé, les sockets TCP/IP s'ouvrent en ressemblant à des descripteurs de fichiers. Donc este et la section suivante de ce lien pourrait être ce que vous recherchez.

3voto

Matt Blaine Points 2270

Essayez de définir les éléments suivants ainsi que le paramètre tcp_fin_timeout. Cela devrait permettre de fermer TIME_WAIT plus rapidement.

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

1 votes

Attention ! J'en ai fait la dure expérience. "Cela peut provoquer des trames abandonnées avec l'équilibrage de charge et les NATs, ne l'utilisez que pour un serveur qui ne communique que sur votre réseau local." - wiki.archlinux.org/index.php/Sysctl

0 votes

@Henk Je suppose que c'est le cas tcp_tw_recycle qui est potentiellement dangereux. tcp_tw_reuse est plus sûr et je ne vois pas de raison de les utiliser simultanément.

2voto

Pawel Pabich Points 818

L'apache(1) standard était prédéfini pour supporter seulement 250 connexions simultanées - si vous en vouliez plus, il y avait un fichier d'en-tête à modifier pour permettre plus de sessions simultanées. Je ne sais pas si c'est toujours le cas avec Apache 2.

De plus, vous devez ajouter une option permettant d'autoriser un plus grand nombre de descripteurs de fichiers ouverts pour le compte qui exécute Apache - ce que les commentaires précédents ne précisent pas.

Faites attention à vos paramètres de travail et au type de délai d'attente (keepalive timeout) que vous avez dans Apache lui-même, au nombre de serveurs "spare ones" que vous faites tourner en même temps, et à la vitesse à laquelle ces processus supplémentaires sont tués.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X