Warum trennt mein Webserver Verbindungen mit einem TCP-Reset bei hoher Last?

10

Ich habe ein kleines VPS-Setup mit Nginx. Ich möchte so viel Leistung wie möglich daraus ziehen, also habe ich mit Optimierung und Lasttests experimentiert.

Ich verwende Blitz.io, um Lasttests durchzuführen, indem ich eine kleine statische Textdatei erhalte und auf ein seltsames Problem stoße, bei dem der Server TCP-Resets zu senden scheint, sobald die Anzahl der gleichzeitigen Verbindungen ungefähr 2000 erreicht. Ich weiß, dass dies ein sehr großes Problem ist große Menge, aber durch die Verwendung von htop hat der Server immer noch viel Zeit und Arbeitsspeicher zu sparen. Daher möchte ich die Ursache dieses Problems herausfinden, um zu sehen, ob ich es noch weiter vorantreiben kann.

Ich verwende Ubuntu 14.04 LTS (64-Bit) auf einem 2 GB Linode VPS.

Ich habe nicht genug Ruf, um dieses Diagramm direkt zu veröffentlichen. Hier ist ein Link zum Blitz.io-Diagramm:

Geben Sie hier die Bildbeschreibung ein

Hier sind Dinge, die ich getan habe, um die Ursache des Problems herauszufinden:

  • Der Nginx-Konfigurationswert worker_rlimit_nofileist auf 8192 festgelegt
  • haben nofileauf 64000 für harte und weiche Grenzwerte für rootund www-dataBenutzer (als was nginx läuft) in eingestellt/etc/security/limits.conf
  • Es gibt keine Anzeichen dafür, dass etwas schief geht /var/log/nginx.d/error.log(normalerweise druckt nginx Fehlermeldungen, wenn Sie auf Dateideskriptor-Grenzwerte stoßen).

  • Ich habe ufw Setup, aber keine Regeln zur Ratenbegrenzung. Das ufw-Protokoll zeigt an, dass nichts blockiert wird, und ich habe versucht, ufw mit demselben Ergebnis zu deaktivieren.

  • Es gibt keine indikativen Fehler in /var/log/kern.log
  • Es gibt keine indikativen Fehler in /var/log/syslog
  • Ich habe die folgenden Werte hinzugefügt /etc/sysctl.confund sie sysctl -pohne Wirkung geladen :

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

Irgendwelche Ideen?

EDIT: Ich habe einen neuen Test durchgeführt und auf 3000 Verbindungen in einer sehr kleinen Datei (nur 3 Bytes) hochgefahren. Hier ist das Blitz.io-Diagramm:

Blitz.io Grafik

Laut Blitz sind alle diese Fehler "TCP Connection Reset" -Fehler.

Hier ist das Linode-Bandbreitendiagramm. Beachten Sie, dass dies ein 5-Minuten-Durchschnitt ist, sodass der Tiefpass etwas gefiltert wird (die momentane Bandbreite ist wahrscheinlich viel höher), aber dennoch ist dies nichts:

Geben Sie hier die Bildbeschreibung ein

ZENTRALPROZESSOR:

Geben Sie hier die Bildbeschreibung ein

E / A:

Geben Sie hier die Bildbeschreibung ein

Hier ist gegen htopEnde des Tests: htop

Ich habe auch einen Teil des Datenverkehrs mit tcpdump in einem anderen (aber ähnlich aussehenden) Test erfasst und die Erfassung gestartet, als die Fehler auftraten: sudo tcpdump -nSi eth0 -w /tmp/loadtest.pcap -s0 port 80

Hier ist die Datei, wenn jemand sie sich ansehen möchte (~ 20 MB): https://drive.google.com/file/d/0B1NXWZBKQN6ETmg2SEFOZUsxV28/view?usp=sharing

Hier ist ein Bandbreitendiagramm von Wireshark:

Geben Sie hier die Bildbeschreibung ein (Zeile ist alle Pakete, blaue Balken sind TCP-Fehler)

Aus meiner Interpretation des Captures (und ich bin kein Experte) geht hervor, dass die TCP-RST-Flags von der Lasttestquelle und nicht vom Server stammen. Unter der Annahme, dass auf der Seite des Lasttestdienstes etwas nicht stimmt, kann man dann davon ausgehen, dass dies das Ergebnis einer Art Netzwerkverwaltung oder DDOS-Minderung zwischen dem Lasttestdienst und meinem Server ist?

Vielen Dank!

Erik Swan
quelle
Führt Ihr Provider eine Art DDoS-Minderung durch? Dies kann Ihren Test beeinträchtigen.
Michael Hampton
@ MichaelHampton Ich bin mir ziemlich sicher, dass Linode das nicht tut.
EEAA
Können Sie das Netzwerkdiagramm über das Linode-Kontrollfeld veröffentlichen? Wie viel Bandbreite beansprucht dieser Test tatsächlich?
EEAA
Ich habe ein bisschen mehr Nachforschungen angestellt und den ursprünglichen Beitrag mit vielen weiteren Informationen aktualisiert. Ich habe auch mit Linode bestätigt, dass sie keine DDOS-Minderung durchführen, obwohl dies nicht unbedingt bedeutet, dass ein Netzwerkanbieter zwischen dem Lasttestdienst und Linode keine Maßnahmen ergreift. Vielen Dank!
Erik Swan
1
Gibt es einen Grund, warum Sie nur net.core.netdev_max_backlogbis 2000 eingerichtet haben? Einige Beispiele, die ich gesehen habe, haben es um eine Größenordnung höher für Gigabit- (und 10Gig-) Verbindungen.
Moshe Katz

Antworten:

1

Es kann eine beliebige Anzahl von Quellen für das Zurücksetzen der Verbindung geben. Der Lasttester verfügt möglicherweise nicht über die verfügbaren kurzlebigen Ports, über die eine Verbindung hergestellt werden kann. Bei einem Gerät auf dem Weg (z. B. einer Firewall, die NAT ausführt) ist der NAT-Pool möglicherweise erschöpft und es kann kein Quellport für die Verbindung bereitgestellt werden ein Load Balancer oder eine Firewall an Ihrem Ende, die möglicherweise ein Verbindungslimit erreicht hat? Wenn Sie Quell-NAT für den eingehenden Datenverkehr ausführen, kann dies auch zu einer Erschöpfung des Ports führen.

Man würde wirklich eine PCAP-Datei von beiden Seiten brauchen. Sie möchten suchen, wenn ein Verbindungsversuch gesendet wird, der Server jedoch nie erreicht, aber dennoch so angezeigt wird, als ob er vom Server zurückgesetzt wurde. Wenn dies der Fall ist, musste etwas entlang der Linie die Verbindung zurücksetzen. Die Erschöpfung des NAT-Pools ist eine häufige Ursache für diese Art von Problemen.

Außerdem kann netstat -st Ihnen einige zusätzliche Informationen geben.

GeorgeB
quelle
1

Einige Ideen zum Ausprobieren, basierend auf meinen jüngsten ähnlichen Tuning-Erfahrungen. Mit Referenzen:

Sie sagen, es ist eine statische Textdatei. Nur für den Fall, dass eine Upstream-Verarbeitung stattfindet, verbessern Domain-Sockets anscheinend den TCP-Durchsatz über eine TC-Port-basierte Verbindung:

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

Unabhängig von der vorgelagerten Beendigung:

Aktivieren Sie multi_accept und tcp_nodelay: http://tweaked.io/guide/nginx/

Deaktivieren Sie den langsamen TCP-Start: /programming/17015611/disable-tcp-slow-start http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

Optimieren Sie das TCP-Überlastungsfenster (initcwnd): http://www.nateware.com/linux-network-tuning-for-2013.html

JayMcTee
quelle
1

Um die maximale Anzahl geöffneter Dateien festzulegen (falls dies Ihr Problem verursacht), müssen Sie /etc/sysctl.conf "fs.file-max = 64000" hinzufügen

Sean1e
quelle
0

Überprüfen Sie TIME_WAITmit dem Befehl , wie viele Ports sich im Status befinden, netstat -patunl| grep TIME | wc -lund wechseln Sie net.ipv4.tcp_tw_reusezu 1.

fgbreel
quelle
Wie würde ich sehen, wie viele Häfen sich im TIME_WAITBundesstaat befinden?
Erik Swan
Verwenden von netstatoder ss. Ich habe meine Antwort mit dem vollständigen Befehl aktualisiert!
fgbreel
Ich habe den Test erneut ausgeführt und watch -n 1 'sudo netstat -patunl | grep TIME | wc -l'gebe während des gesamten Tests 0 zurück. Ich bin mir ziemlich sicher, dass die Resets aufgrund einer DDOS-Abschwächung durch jemanden zwischen dem Lasttester und meinem Server erfolgen, basierend auf meiner Analyse der oben veröffentlichten PCAP-Datei, aber wenn jemand bestätigen könnte, dass dies großartig wäre!
Erik Swan