Wenn Apache Bench auf demselben Server wie die Website ausgeführt wird, etwa:
ab -n 1000 -c 10 localhost:8080/
Wenn ich es mit Benutzern vergleiche, die von verschiedenen Standorten aus auf den Server zugreifen, erhalte ich höchstwahrscheinlich keine genauen Ergebnisse.
Ich versuche zu verstehen, wie oder vielmehr warum sich dies auf die Leistung in der Praxis auswirkt, da ein Benutzer in China andere Latenzprobleme hat als jemand im selben Staat/Land.
Angenommen, mein Webserver hat ein maximales Thread-Limit von 100.
Kann jemand im Detail erklären, wie sich die Endbenutzerlatenz auf die Serverleistung auswirken kann/wird?
Ich gehe hier davon aus, dass jede Anfrage gleichmäßig berechnet wird, beispielsweise in 10 ms.
Was ich nicht verstehe, ist, wie sich externe Faktoren auf die Gesamtleistung des Servers auswirken können, insbesondere Internetverbindungen (Standort oder sogar Geräte wie Mobiltelefone) und HTTP/TCP-Handshakes usw.
Antwort1
Im Allgemeinen hat die Endbenutzerlatenz keinen Einfluss auf die Serverleistung. Der Hauptunterschied besteht darin, dass Ihr Server bei höherer Endbenutzerlatenz mehr Verbindungen gleichzeitig hat, da jede Verbindung etwas länger dauert. Der Server erledigt jedoch für jede Verbindung immer noch ungefähr die gleiche Menge an Arbeit. Solange Sie nicht an Serverbeschränkungen, vor allem Speicherbeschränkungen, stoßen, spielt dies keine Rolle.
Der Server beginnt erst mit der Verarbeitung schwerer Verbindungsaufgaben, wenn er die gesamte Anforderung erhalten hat. Wenn es also länger dauert, die Verbindung herzustellen und die Anforderung abzurufen, bedeutet das nur, dass der Server etwas länger wartet und im Grunde nichts tut, bevor er mit der eigentlichen Verarbeitung beginnt.
Normalerweise verarbeitet der Server die Anfrage und stellt die Antwort in einem Durchgang in die Warteschlange. Aufgrund von Client- und Netzwerklatenz kann es dann etwas länger dauern, diese Warteschlange zu leeren. Aber der Teil des Servers, der dies verarbeitet, ist stark optimiert und die Logik für die jeweilige Seite oder das jeweilige Objekt wurde bereits vollständig ausgeführt, um die Antwort zu generieren. Daher gibt es auch hier normalerweise keine nennenswerten Auswirkungen auf die Serverleistung.
Die Client-Erfahrung kann jedoch viel schlechter sein. Dies gilt insbesondere dann, wenn der Dienst häufig Fälle hat, in denen der Client Informationen vom Server abrufen und dann eine Verbindung herstellen muss, um weitere Informationen abzurufen. Wenn beispielsweise eine Webseite den Client anweist, eine Reihe von Frames zu laden, und diese Frames den Client dann anweisen, eine Reihe von Bildern zu laden, werden viele „Hin- und Her“-Operationen (jede davon erhöht durch die Netzwerklatenz) ausgeführt, bevor der Client ein Ergebnis sieht. Aber der Server erledigt die gleiche Menge an Arbeit.
Antwort2
Eigentlich ist das kein Problem, sofern Sie nicht über einen Supercomputer verfügen, der in Echtzeit arbeitet, mehrere Prozessoren gleichzeitig unterstützt (sagen wir mit 1.000 CPUs) und über viel Speicher verfügt ...
In einem Multiprozesssystem haben alle Prozesse ein Zeitfenster, das genannt wird Quantum Size
. Betriebssysteme mit Multiprozessfähigkeiten, was etwa von den 80er- bis zu den 90er-Jahren bis heute der Fall ist, wechseln zwischen laufenden Prozessen hin und her und geben jedem von ihnen diese Quantengröße. Dieses Zeitfenster beträgt in unseren modernen Betriebssystemen etwa 20 Millisekunden und dieser Wechsel erfolgt sehr schnell mit sehr geringem Wechselaufwand. Nehmen wir an, wir haben eine CPU, zwischen der in 1 Sekunde, was 1000 Millisekunden entspricht, zwischen zwei Prozessen umgeschaltet wird, können wir sie 900-950-980 (vielleicht) Millisekunden lang laufen lassen (der Unterschied ist beim Prozesswechsel weg). Wie gesagt, dieser Wechsel erfolgt sehr schnell und stellen Sie sich 50 laufende Prozesse vor. Wir sehen, dass alle Prozesse gleichzeitig laufen. Tatsächlich sind sie das nicht und das ist Multiprocessing, die Grundlagen der Prozessplanung ...
Wenn wir mehrere Threads in Prozessen haben, plant das Betriebssystem zuerst den Prozess und gibt ihm ein Quantum, dann plant es die Threads in diesem Prozess. Und in diesem Quantum werden auch Threads geplant. Wenn das gesamte Quantum endet, plant das Betriebssystem einen anderen Prozess (oder denselben gemäß dem Planungsalgorithmus) und auch Threads in diesem neuen Prozess werden geplant.
Es gibt zwei Ebenen der Ausführungsumgebung für Threads. Eine ist die Benutzerebene, zwei sind die Kernelebene. Die, die ich oben erwähnt habe, ist die Benutzerebene. Prozessplanung, Threadplanung in dieser Quantengröße. Aber wenn Sie auf die Kernelebene gehen, kann der Scheduler verschiedene Threads aus verschiedenen Prozessen planen. Das Quantum wird direkt auf der Kernelebene auf Threads angewendet ...
Nachdem wir das alles besprochen haben, wollen wir beginnen zu verstehen, wie sich eine Latenzzeit am Ende einer Verbindung auf die Serverleistung auswirken kann:
Ihre Threads müssen auf Kernelebene sein, wenn Sie maximale Leistung wollen, und ich weiß, dass Apache-Threads nicht im Kernelmodus sind. Apache selbst ist im Benutzermodus, es ist eine Benutzeranwendung und seine Threads laufen im Benutzerebenenmodus. Sie werden also auf keinen Fall 100 % Leistung von diesem Server bekommen... Nehmen wir an, die Threads laufen im Kernelmodus und Sie haben zwei CPUs. Ein Thread für die erste CPU, ein Thread für die zweite. Jetzt laufen wirklich zwei Threads gleichzeitig. Ein Web-Worker-Thread ist I/O Bounded
aus Sicht des Betriebssystems eigentlich ein Thread und wenn er eine Datei anfordert, wird er blockiert, bis die Datei bereit ist. Der Scheduler plant die Ausführung eines anderen Worker-Threads. Wenn „diese“ Datei bereit ist, wird der blockierte Thread in die Warteschlange verschoben und erneut geplant. So weiter, so gut... Was passiert, wenn Sie 100 Worker-Threads haben? Diese Frage wirft eine weitere Frage auf: Wann wird ein Worker-Thread erstellt?
Bei Webserveranwendungen wird ein Worker-Thread erstellt, wenn low-level IP connection is made
. Ihre eigentlichen beiden Threads laufen also bereits, eine neue Verbindung wird von der Hardware hergestellt (sie haben ihre eigenen PUs und unterbrechen das Hauptsystem zur Datenübertragung), ein neuer Worker-Thread ist aufgetaucht und wurde zur Planung an die Warteschlange gesendet ...
Zurück zum Hauptthema, wie ein externer Faktor die Systemleistung beeinflusst. Es dreht sich alles um Systembeschränkungen. Die Anzahl der Threads beeinflusst die Leistung, unabhängig davon, ob das System über genügend Prozesseinheiten verfügt, um sie zu verarbeiten oder nicht. Einfache Mathematik: Zwei Prozessoren verarbeiten nur zwei Threads gleichzeitig ... Die Bandbreite der Netzwerkverbindung beeinflusst die Leistung durch „wie viele Verbindungen sie akzeptieren kann“. Angenommen, eine Verbindung hat 10 Byte Daten und eine Bandbreite von 100 Byte pro Sekunde, dann können Sie 10 Verbindungen pro Sekunde haben ...
Die Skalierung liegt bei Ihnen. Sie müssen nur eines bedenken: Ihre gesamte CPU-Ressource verarbeitet bereits die Threads, die sich bereits in der Warteschlange befinden. Wenn also ein neuer Thread auftaucht, wird die Situation für die vorhandenen Threads nicht schlechter.
Beim ersten Start der Server-App kann die Leistung ein Problem darstellen. Schnell wird die Höchstgrenze erreicht. Es ist wie bei der Beschleunigung eines Autos. Es beschleunigt zuerst und erreicht nach einiger Zeit die Höchstgeschwindigkeit. Sie können mit Höchstgeschwindigkeit fahren, bis Ihnen das Benzin ausgeht oder Sie den Fuß vom Gaspedal nehmen.