Pourquoi mon server Web supprime-t-il les connections avec une réinitialisation TCP à une charge élevée?

J'ai une petite configuration VPS avec nginx. Je souhaite écraser autant de performance que possible, donc j'ai expérimenté l'optimization et le test de charge.

J'utilise Blitz.io pour faire des tests de chargement en obtenant un petit file text statique et en cours d'exécution dans un problème étrange où le server semble envoyer des réinitialisations TCP une fois que le nombre de connections simultanées atteint approximativement 2000. Je sais que c'est un très une grande quantité, mais de l'utilisation de htop, le server a encore beaucoup à perdre dans le time et la memory de la CPU, alors j'aimerais find la source de ce problème pour voir si je peux le pousser encore plus loin.

J'utilise Ubuntu 14.04 LTS (64 bits) sur un VPS Linde de 2 Go.

Je n'ai pas assez de réputation pour publier ce graphique directement, alors voici un lien vers le graphique Blitz.io:

entrez la description de l'image ici

Voici les choses que j'ai faites pour essayer de comprendre la source du problème:

  • La valeur de configuration nginx worker_rlimit_nofile est définie sur 8192
  • nofile réglé sur 64000 pour les limites dures et douces pour l'user root et www-data (ce que nginx s'exécute) dans /etc/security/limits.conf
  • il n'y a aucune indication de quoi ne va pas dans /var/log/nginx.d/error.log (généralement, si vous utilisez des limites de descripteur de file, nginx va imprimer des messages d'erreur en disant)

  • J'ai une configuration ufw, mais pas de règles limitant les taux. Le journal ufw indique que rien n'est bloqué et j'ai essayé de désactiver ufw avec le même résultat.

  • Il n'y a pas d'erreur indicative dans /var/log/kern.log
  • Il n'y a pas d'erreur indicative dans /var/log/syslog
  • J'ai ajouté les valeurs suivantes à /etc/sysctl.conf et les /etc/sysctl.conf chargé avec sysctl -p sans effet:

     net.ipv4.tcp_max_syn_backlog = 1024 net.core.somaxconn = 1024 net.core.netdev_max_backlog = 2000 

Des idées?

EDIT: J'ai fait un nouveau test, en rampe à 3000 connections sur un très petit file (seulement 3 octets). Voici le graphique Blitz.io:

Blitz.io graph

Encore une fois, selon Blitz, toutes ces erreurs sont des erreurs "Réinitialisation de la connection TCP".

Voici le graphique de bande passante Linode. Gardez à l'esprit qu'il s'agit d'une moyenne de 5 minutes, donc le passage passe-bas un peu (la bande passante instantanée est probablement beaucoup plus élevée), mais ce n'est rien:

entrez la description de l'image ici

CPU:

entrez la description de l'image ici

I / O:

entrez la description de l'image ici

Voici le point htop près de la fin du test: htop

J'ai également capturé une partie du trafic en utilisant tcpdump sur un test différent (mais similaire), en commençant la capture lorsque les erreurs ont commencé à entrer: sudo tcpdump -nSi eth0 -w /tmp/loadtest.pcap -s0 port 80

Voici le file si quelqu'un veut le regarder (~ 20 Mo): https://drive.google.com/file/d/0B1NXWZBKQN6ETmg2SEFOZUsxV28/view?usp=sharing

Voici un graphique de bande passante de Wireshark:

entrez la description de l'image ici (Ligne est tous les packages, les barres bleues sont des erreurs TCP)

À partir de mon interprétation de la capture (et je ne suis pas un expert), il semble que les drapeaux TCP RST proviennent de la source de test de chargement et non du server. Alors, en supposant que quelque chose ne soit pas faux du côté du service de test de charge, est-il sûr de supposer que cela résulte d'une sorte de gestion de réseau ou d'atténuation DDOS entre le service de test de charge et mon server?

Merci!

Pour définir le nombre maximum de files ouverts (si cela cause votre problème), vous devez append "fs.file-max = 64000" à /etc/sysctl.conf

S'il vous plaît, regardez combien de ports sont dans l'état TIME_WAIT utilisant la command netstat -patunl| grep TIME | wc -l netstat -patunl| grep TIME | wc -l netstat -patunl| grep TIME | wc -l et changez net.ipv4.tcp_tw_reuse à 1.

Il pourrait y avoir un certain nombre de sources de réinitialisation de connection. Le testeur de charge pourrait être hors des ports éphémères disponibles à partir desquels lancer une connection, un périphérique en cours (comme un pare-feu faisant NAT) pourrait avoir son pool NAT épuisé et ne peut pas fournir un port source pour la connection, est-il là un équilibreur de charge ou un pare-feu à votre extrémité qui pourrait avoir atteint une limite de connection? Et si l'on effectue la NAT source sur le trafic entrant, cela pourrait également subir l'épuisement des ports.

On aurait vraiment besoin d'un file pcap des deux extrémités. Ce que vous voulez searchr est si une tentative de connection est envoyée mais n'atteint jamais le server mais apparaît toujours comme si elle avait été réinitialisée par le server. Si tel est le cas, quelque chose sur la ligne devait réinitialiser la connection. L'épuisement de la piscine NAT est une source commune de ces types de problèmes.

En outre, netstat -st pourrait vous donner quelques informations supplémentaires.

Quelques idées à essayer, en fonction de mes propres expériences d'actualisation similaires récentes. Avec des references:

Vous dites que c'est un file text statique. Juste au cas où il y a un traitement en amont en cours, apparemment les sockets de domaine améliorent le débit TCP sur une connection au port TC:

https://rtcamp.com/tutorials/php/fpm-sysctl-tweaking/ https://engineering.gosquared.com/optimising-nginx-node-js-and-networking-for-heavy-workloads

Indépendamment de la fin de l'amont:

Activer multi_accept et tcp_nodelay: http://tweaked.io/guide/nginx/

Désactiver le démarrage lent TCP: https://stackoverflow.com/questions/17015611/disable-tcp-slow-start http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

Optimiser la window de congestion TCP (initcwnd): http://www.nateware.com/linux-network-tuning-for-2013.html