Was begrenzt die maximale Anzahl von Verbindungen auf einem Linux-Server?

89

Welche Kernelparameter oder andere Einstellungen steuern die maximale Anzahl von TCP-Sockets, die auf einem Linux-Server geöffnet sein können? Was sind die Kompromisse, wenn mehr Verbindungen zugelassen werden?

Beim Auslastungstest eines Apache-Servers mit ab ist mir aufgefallen, dass es ziemlich einfach ist, die offenen Verbindungen auf dem Server zu maximieren. Wenn Sie die Option -k auslassen, die die Wiederverwendung der Verbindung ermöglicht, und mehr als 10.000 Anfragen senden, werden die ersten 11.000 Anfragen von Apache bearbeitet und 60 Sekunden lang angehalten. Ein Blick auf die netstat-Ausgabe zeigt 11.000 Verbindungen im Status TIME_WAIT. Anscheinend ist das normal. Aus Gründen der TCP-Zuverlässigkeit werden Verbindungen standardmäßig 60 Sekunden lang geöffnet gehalten, auch nachdem der Client sie beendet hat .

Es scheint, als wäre dies eine einfache Möglichkeit, einen Server zu tun, und ich frage mich, wie die üblichen Einstellungen und Vorsichtsmaßnahmen dafür aussehen.

Hier ist meine Testausgabe:

# 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

Hier ist der Befehl netstat, den ich während des Tests ausführe:

 # 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
Ben Williams
quelle

Antworten:

64

Schließlich fand ich die Einstellung , die wirklich wurde die Anzahl der Verbindungen zu beschränken: net.ipv4.netfilter.ip_conntrack_max. Dieser Wert wurde auf 11.776 festgelegt. Was auch immer ich eingestellt habe, ist die Anzahl der Anforderungen, die ich in meinem Test bearbeiten kann, bevor ich tcp_fin_timeoutSekunden warten muss, bis weitere Verbindungen verfügbar sind. Der conntrackKernel verwendet die Tabelle, um den Status der Verbindungen zu verfolgen. Sobald die Tabelle voll ist, beginnt der Kernel, Pakete zu verwerfen und diese im Protokoll zu drucken:

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

Der nächste Schritt bestand darin, den Kernel dazu zu bringen, alle Verbindungen im TIME_WAITStatus wiederherzustellen, anstatt Pakete zu verwerfen. Ich könnte dies entweder durch Einschalten tcp_tw_recycleoder durch Erhöhen ip_conntrack_maxder Anzahl der lokalen Ports erreichen, die für Verbindungen von zur Verfügung gestellt werden ip_local_port_range. Ich denke, sobald der Kernel keine lokalen Ports mehr hat, beginnt er, Verbindungen zu recyceln. Hierfür werden mehr Speicherverfolgungsverbindungen verwendet, aber es scheint die bessere Lösung als das Einschalten zu sein, tcp_tw_recycleda die Dokumente implizieren, dass dies gefährlich ist.

Mit dieser Konfiguration kann ich ab den ganzen Tag laufen und nie aus Verbindungen heraus laufen:

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

Die tcp_max_orphansEinstellung hatte keinen Einfluss auf meine Tests und ich weiß nicht warum. Ich würde denken, dass es die Verbindungen in TIME_WAITZustand schließen würde, sobald es 8192 von ihnen gab, aber es tut das nicht für mich.

Ben Williams
quelle
3
Wo konfigurieren wir diese Parameter?
Codevalley
2
@Codevalley Das mag systemabhängig sein, aber auf Ubuntu Server werden sie um
Ben Williams
24

Sie möchten sich unbedingt ansehen, was das / proc-Dateisystem Ihnen in dieser Hinsicht zu bieten hat.

Auf dieser letzten Seite finden Sie möglicherweise Folgendes, das Sie interessiert:

Avery Payne
quelle
tcp_max_orphans ist interessant, scheint aber nicht zu funktionieren. Wenn ich versuche, verwaiste Steckdosen während meines Tests zu messen, sehe ich 11.651 davon, während tcp_max_orphans 8.092 ist. # netstat --inet -p | grep "localhost: www" | sed-es / \ + / / g '| cut -d '' -f 1-4,6-7 | sortieren | uniq -c 11651 tcp 0 0 localhost: www TIME_WAIT -
Ben Williams
Schauen Sie sich die Einstellung "tcp_orphan_retries" an - die Idee ist, dass die Sockets schneller "gekeult" werden ...
Avery Payne,
@Jauder Hos Vorschlag + tcp_orphan_retries klingt wie ein potenzieller Gewinn für Ihre Situation.
Avery Payne
3

Ich glaube nicht, dass es ein Tunable gibt, mit dem man das direkt einstellen kann. Dies fällt unter die Kategorie der TCP / IP-Optimierung. Um herauszufinden, was Sie tun können, probieren Sie 'man 7 tcp'. Mit dem sysctl ('man 8 sysctl') werden diese gesetzt. 'sysctl -a | grep tcp 'zeigt Ihnen das meiste, was Sie tun können, aber ich bin nicht sicher, ob es alle zeigen wird. Sofern sich dies nicht geändert hat, sehen die geöffneten TCP / IP-Sockets wie Dateideskriptoren aus. So dies und der nächste Abschnitt in dieser Verbindung könnte das sein , was Sie suchen.

Kyle Brandt
quelle
2

Versuchen Sie, das Folgende sowie tcp_fin_timeout festzulegen. Dies sollte TIME_WAIT schneller schließen.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
Jauder Ho
quelle
Vorsicht hier! Auf die harte Tour erlebt. "Dies kann zu ausgelassenen Frames mit Lastenausgleich und NATs führen. Verwenden Sie diese Option nur für einen Server, der nur über Ihr lokales Netzwerk kommuniziert." - wiki.archlinux.org/index.php/Sysctl
Henk
@Henk Ich schätze, tcp_tw_recycledas ist potenziell gefährlich. tcp_tw_reuseist sicherer und ich sehe keinen Grund, sie gleichzeitig zu verwenden.
Vladislav Rastrusny
2

Der Standard-Apache (1) wurde vordefiniert, um nur 250 gleichzeitige Verbindungen zu unterstützen. Wenn Sie mehr wollten, musste eine Header-Datei geändert werden, um mehr gleichzeitige Sitzungen zu ermöglichen. Ich weiß nicht, ob dies bei Apache 2 immer noch zutrifft.

Außerdem müssen Sie eine Option hinzufügen, mit der für das Konto, auf dem Apache ausgeführt wird, eine Vielzahl offener Dateideskriptoren zugelassen werden. Dies wird in den vorherigen Kommentaren nicht erwähnt.

Achten Sie auf Ihre Worker-Einstellungen und darauf, welche Art von Keepalive-Timeouts in Apache selbst auftreten, wie viele Ersatzserver auf einmal ausgeführt werden und wie schnell diese zusätzlichen Prozesse beendet werden.

rasjani
quelle
1

Sie können die im Status TIME_WAIT verbrachte Zeit reduzieren (Net.ipv4.tcp_fin_timeout festlegen). Sie könnten Apache durch YAWS oder Nginx oder ähnliches ersetzen.

Kompromisse bei mehr Verbindungen sind im Allgemeinen mit der Speichernutzung verbunden, und wenn Sie einen Verzweigungsprozess haben, überlasten viele untergeordnete Prozesse Ihre CPU.

Devdas
quelle
1
tcp_fin_timeout dient nicht zum Festlegen des TIME-WAIT-Ablaufs, der außerhalb der Neuerstellung des Kernels nicht geändert werden kann, sondern für FIN, wie der Name angibt.
Alexandr Kurilin
0

Die absolute Anzahl von Sockets, die für eine einzelne IP-Adresse geöffnet sein können, beträgt 2 ^ 16 und wird von TCP / UDP definiert, nicht vom Kernel.

Jason Tan
quelle
6
Nein, ist es nicht. Sie können weitere öffnen, da der lokale Port nicht eindeutig sein muss, solange sich die Remoteadressen unterscheiden. Außerdem sagte das OP pro Server, und Sie können> 1 Adresse pro Server haben.
MarkR