Bonjour,
je rencontre un problème d'établissement de connexions TCP sur un serveur par forte charge, qui se concrétise par des timeouts de connexion. Ce serveur établit de nombreuses connexions : - serveur web NGiNX - fichiers statiques sur NFSv4 (4 connexions TCP) - reverse-proxy sur une 20ène de serveurs web Apache2/PHP, via l'IP publique - reverse-proxy sur un cluster XMPP
Evidemment il y a quelques axes d'améliorations simple : passer par le réseau privé pour limiter les connexions sur l'interface réseau publique, ... mais ce n'est pas le but de ce mail.
Sous forte charge, parfois une simple connexion TCP a des difficultés pour s'établir. Pour tester, j'écarte des soucis potentiels avec NGiNX et lance un serveur netcat sur le port 8080 : nc -l -k 8080
et depuis un poste client sous Linux : while true; do date -R | tee -a /dev/stderr | nc -w 2 perceval.local 8080 || echo ERR; sleep 0.2; done
Lorsque le problème survient, des "ERR" s'affichent.
A ce moment, j'ai tenté plusieurs choses pour tenter de trouver la source de ces problèmes de connexions, et aucun ne s'est avéré "payant" : - désactiver le firewall - supprimer et décharger conntrack - changer l'algorythme de congestion TCP de cubic à autre chose - mesurer le nombre de connexions TCP établit ou en FIN_WAIT : à 10k total le soucis peut très bien se produire ou pas - modifier plusieurs paramètre de config TCP / Kernel : net.ipv4.tcp_sack = 1 net.ipv4.tcp_fack = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_syncookies = 0 net.ipv4.tcp_low_latency = 0 net.core.netdev_max_backlog = 4000 net.ipv4.ip_local_port_range = 1024 65000 net.ipv4.tcp_max_syn_backlog = 163840 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_no_metrics_save = 1 net.ipv4.tcp_max_tw_buckets = 400000 net.core.somaxconn = 8192 fs.file-max = 1310720 net.ipv4.tcp_tw_recycle=1 net.ipv4.tcp_tw_reuse=1
En vain. Sauf un paramètre qui débloque tout quand il est désactivé : net.ipv4.tcp_timestamps=0
C'est très net, si je désactive les timestamps TCP coté serveur (ou coté client forcément), je n'ai plus aucun problème d'établissement de connexions TCP.
A ce moment commence les recherches sur Google, et tout ce que je trouve est ambigu : il vaut mieux activer les timestamps TCP pour des raisons de performances, mais il faut mieux les désactiver pour des problèmes de sécurité. Activé, l'attaquant peut récupérer l'uptime du serveur... Franchement osef nan ? Ce qui me gène plus, c'est qu'il est conseillé d'activer ce paramètre en cas de soucis de congestion TCP...
Peut-être qu'avec la quantité de trafic, le kernel n'est pas capable de fournir assez de timestamps ? Peut-être que la fréquence du timer Linux a une incidence ? Le kernel utilisé est le 3.5.5 avec les patchs Google d'activé (RPS, RFS) et cette config de timer : CONFIG_NO_HZ=y CONFIG_HZ_250=y CONFIG_HZ=250
J'essaye avec 1000 HZ : aucune incidence.
La désactivation de ce paramètre net.ipv4.tcp_timestamps ne doit pas agir que sur les timestamps, peut-être que les algos de congestion TCP, ou certains modules, ou une partie de la stack TCP, utilisent les timestamps TCP, et peut-être que c'est un de ces modules qui pose problème ?
Avez vous déjà expérimenté ce type de soucis ? Je suis dispo pour faire des tests si vous avez des idées !!