Warum sollten Sie MaxKeepAliveRequests jemals auf etwas anderes als unbegrenzt setzen?

11

Apache ist KeepAliveTimeoutvorhanden, um eine Keep-Alive-Verbindung zu schließen, wenn innerhalb eines bestimmten Zeitraums keine neue Anforderung ausgegeben wird. Vorausgesetzt, der Benutzer schließt seinen Browser / Tab nicht, schließt dieses Zeitlimit (normalerweise 5 bis 15 Sekunden) die meisten Keep-Alive-Verbindungen und verhindert, dass Serverressourcen verschwendet werden, indem Verbindungen auf unbestimmte Zeit beibehalten werden.

Jetzt begrenzt die MaxKeepAliveRequestsDirektive die Anzahl der HTTP-Anforderungen, die eine einzelne TCP-Verbindung (die aufgrund von offen KeepAlivebleibt) bedienen wird. Wenn Sie dies auf setzen 0, ist eine unbegrenzte Anzahl von Anforderungen zulässig.

Warum würden Sie dies jemals auf etwas anderes als "unbegrenzt" einstellen? Wenn ein Kunde noch aktiv Anfragen stellt, welchen Schaden hat es dann, wenn diese auf derselben Keep-Alive-Verbindung ausgeführt werden? Sobald das Limit erreicht ist, gehen die Anforderungen nur bei einer neuen Verbindung ein.

So wie ich das sehe, macht es keinen Sinn, dies jemals einzuschränken. Was vermisse ich?

Jonathon Reinhart
quelle

Antworten:

4

Grundsätzlich, weil Apache nicht dafür gebaut wurde. Das Problem ist die Speichernutzung des Servers. In vielen Konfigurationen erfolgt die Inhaltserstellung im selben Prozess wie die Bereitstellung von Inhalten, sodass jeder Prozess auf die Größe des größten von ihm verarbeiteten Objekts anwächst. Stellen Sie sich einen Prozess vor, der aufgrund eines umfangreichen PHP-Skripts auf 64 MB erweitert wird, und dann diesen aufgeblähten Prozess, der statische Dateien enthält. Multiplizieren Sie dies jetzt mit 100. Wenn irgendwo Speicherlecks auftreten, wachsen die Prozesse unbegrenzt.

Die Keepalive-Einstellungen sollten basierend auf der Art Ihres Inhalts und Ihrem Datenverkehr ausgewogen sein. Im Allgemeinen hat die optimale Konfiguration MaxKeepAliveRequests hoch (100-500) und KeepAliveTimeout niedrig (2-5), um sie schnell freizugeben.

Luftschiff
quelle
2

Ich weiß, dass dies eine alte Frage ist, aber ich habe einige Fehlerbehebungen durchgeführt, und es scheint, als ob (und dies gilt nicht nur für Apache) MaxKeepAliveRequestsunabhängig davon funktioniert KeepAliveTimeout.

Das heißt, die Timeout-Direktive zählt nur für den Leerlauf persistenter Verbindungen (keine Lese- oder Schreibvorgänge). Wenn Sie weiterhin unterhalb des Timeouts anfordern, können Sie praktisch eine unbegrenzte Anzahl von Anforderungen über dieselbe Verbindung ausführen.

Dies ist möglicherweise aus bestimmten Gründen nicht gut, einschließlich der Tatsache, dass lang laufende TCP-Verbindungen zufällig beendet werden. In jedem Fall sind http-Clients nicht so dumm und können mit einer "niedrigen" MaxKeepAliveRequestsEinstellung ziemlich gut umgehen , z. B. ist es in der Programmiersprache relativ einfach zu erkennen, ob eine TCP-Verbindung vom Server geschlossen wurde, und somit erneut eine Verbindung zu ihr herzustellen. Darüber hinaus haben die meisten http-Clients selbst Beschränkungen (z. B. würden Browser nach etwa 300 Sekunden eine Keep-Alive-Verbindung schließen).

Leben des Guenter
quelle
1

Ein Grund wäre der Lastausgleich. Sobald eine Keep-Alive- oder http 1.1-Verbindung hergestellt ist, wird sie vom Load Balancer erst nach dem Schließen auf einen neuen Host verschoben. Wenn ein Client über seine eine Verbindung eine große Anzahl von Anforderungen stellt, wird möglicherweise kein guter Ausgleich zwischen den Servern erzielt.

dtauzell
quelle
Aber warum sollte das wichtig sein? Für mich scheint es unerwünscht, die Verbindung eines einzelnen Benutzers jemals auf mehrere Server zu verteilen. Der Lastausgleich dient dazu, eine hohe Anzahl von Benutzern zu verarbeiten, nicht Verbindungen von einem einzelnen Benutzer. In der Tat - wenn ein einzelner Benutzer einen Dienst hämmert, möchten Sie ihn lieber auf einen einzelnen Server beschränken (auf dem er sich effektiv selbst einschränken würde).
Jonathon Reinhart
1
Gute Argumente. Ein paar Gedanken: 1. Jeder andere auf diesem Server würde ebenfalls gehämmert werden. 2. Für Load Balancer, die unterhalb der HTTP-Ebene arbeiten: Wenn Sie einen Server aus dem Load Balancer-Pool entfernen, wird die vorhandene HTTP-Verbindung nicht geschlossen. Das macht es etwas schwieriger, Leute nur mit dem Load Balancer auf einen anderen Server zu verschieben. Grund 2 ist, wie ich auf diese Seite gekommen bin, als ich gesucht habe, was die Leute zu diesem Parameter zu sagen haben.
Dtauzell
1
Ein dritter Grund: Wenn Ihr Server / Ihre App in einen schlechten Zustand gerät und ein Fehler auftritt, kann dies dazu führen, dass alle Anforderungen fehlerhaft werden, bis die Situation behoben ist. Wenn Sie jedoch die Anzahl der Anfragen begrenzen, können sie auf einen neuen Server ausgeglichen werden .
Dtauzell
1

Teilweise, um zu verhindern, dass ein einzelner Benutzer alle Verbindungssteckplätze belegt. Ohne Einschränkung könnte ein böswilliger oder schlecht geschriebener Client jede einzelne verfügbare Verbindung übernehmen und für immer behalten. Dies ist jedoch keine gute Abschwächung im Vergleich zu einem IP-Verbindungslimit.

Meistens Lastausgleich, aber speziell im Hinblick auf die Wartung. Wenn Sie einen Server offline schalten möchten, löschen Sie ihn auf 0 Verbindungen, lassen jedoch vorhandene Verbindungen für einige Zeit beendet werden. Wenn Sie die Anzahl der Keepalive-Anforderungen begrenzen, erstellen Benutzer möglicherweise ordnungsgemäß eine neue Verbindung und werden auf einen neuen Back-End-Server verschoben. Wahrscheinlich wäre eine Möglichkeit, dem Server zu signalisieren, dass er während des Abflussvorgangs keine Keepalives mehr akzeptieren soll, noch besser, aber soweit ich weiß, gibt es eine solche Funktion nicht.

Elliott
quelle