2013-03-05 4 views

Antwort

16

Welche der beiden oben genannten Strategien besser skaliert und warum?

Thread-pro-Anfrage skaliert besser als Thread-pro-Verbindung.

Java-Threads sind ziemlich teuer und verwenden normalerweise jeweils ein 1-MB-Speichersegment, unabhängig davon, ob sie aktiv oder inaktiv sind. Wenn Sie jeder Verbindung einen eigenen Thread zuweisen, befindet sich der Thread normalerweise zwischen aufeinanderfolgenden Anforderungen für die Verbindung im Leerlauf. Letztendlich muss das Framework entweder keine neuen Verbindungen mehr akzeptieren (weil es keine weiteren Threads mehr erzeugen kann) oder die Verbindung mit alten Verbindungen trennen (was zu einer Verbindungsabwanderung führt, wenn der Benutzer aufwacht).

Die HTTP-Verbindung benötigt wesentlich weniger Ressourcen als ein Thread-Stack, obwohl aufgrund der Funktionsweise von TCP/IP die Anzahl der offenen Verbindungen pro IP-Adresse auf 64 KB begrenzt ist.

Im Gegensatz dazu wird der Thread im Thread-pro-Anfrage-Modell nur zugeordnet, während eine Anfrage verarbeitet wird. Das bedeutet normalerweise, dass der Dienst weniger Threads benötigt, um die gleiche Anzahl von Benutzern zu verwalten. Und da Threads erhebliche Ressourcen benötigen, bedeutet dies, dass der Service besser skalierbar ist.

(Und beachten Sie, dass Thread-pro-Anforderung bedeutet nicht, dass der Rahmen für die HTTP-Verbindung nach jeder Anfrage ... schließen muss)

dass

sagte Nachdem der Thread-pro-Anforderung-Modell ist nicht ideal, wenn während der Bearbeitung jeder Anfrage lange Pausen auftreten. (Und es ist insbesondere nicht ideal, wenn der Dienst den comet-Ansatz verwendet, der das Offenhalten des Antwortstroms für eine lange Zeit beinhaltet.) Um dies zu unterstützen, stellt die Servlet 3.0-Spezifikation einen "asynchronen Servlet" -Mechanismus bereit, der die Anforderungsmethode eines Servlets zulässt Setzen Sie die Verknüpfung mit dem aktuellen Anforderungs-Thread aus. Dies gibt den Thread frei, um eine andere Anfrage zu bearbeiten.

Wenn die Webanwendung so entworfen werden kann, dass sie den "asynchronen" Mechanismus verwendet, ist sie wahrscheinlich skalierbarer als entweder Thread-pro-Anfrage oder Thread-pro-Verbindung.


Followup

Lassen Sie uns eine einzige Webseite mit 1000 Bildern übernehmen. Dies führt zu 1001 HTTP-Anfragen. Nehmen wir weiter an, dass persistente HTTP-Verbindungen verwendet werden. Mit der TPR-Strategie führt dies zu 1001 Thread Pool Management-Operationen (TPMO). Mit der TPC-Strategie führt dies zu 1 TPMO ... Nun, abhängig von den tatsächlichen Kosten für ein einzelnes TPMO, kann ich mir Szenarien vorstellen, in denen TPC besser skaliert werden kann als TPR.

Ich denke, es gibt einige Dinge, die Sie nicht berücksichtigt haben:

  • Der Web-Browser mit vielen URLs konfrontiert zu holen, eine Seite zu vervollständigen können auch offene mehrere Verbindungen.

  • Bei TPC und persistenten Verbindungen muss der Thread warten, bis der Client die Antwort erhält und die nächste Anfrage sendet. Diese Wartezeit kann signifikant sein, wenn die Netzwerklatenz hoch ist.

  • Der Server hat keine Möglichkeit zu wissen, wann eine gegebene (dauerhafte) Verbindung geschlossen werden kann. Wenn der Browser es nicht schließt, könnte es "verweilen" und den TPC-Thread binden, bis der Server die Verbindung abbricht.

  • Die TPMO-Overheads sind nicht groß, besonders wenn Sie die Pool-Overheads von den Context-Switch-Overheads trennen.(Sie müssen das tun, da TPC geht Kontext entstehen schalten auf einer persistenten Verbindungen, siehe oben.)

Mein Gefühl ist, dass diese Faktoren dürften den TPMO Ersparnis mit einem Thread gewidmet überwiegen jede Verbindung.

+0

Sie haben geschrieben "(Und beachten Sie, dass Thread-pro-Anfrage nicht bedeutet, dass das Framework die HTTP-Verbindung nach jeder Anfrage schließen muss ...)". Wenn die Verbindung später wiederverwendet wird, wird derselbe Thread an sie angehängt oder ist es ein anderer Thread? – Geek

+0

Es ist normalerweise ein anderer Thread. –

+0

"* Thread-pro-Anfrage skaliert besser als Thread-pro-Verbindung. *" ... Was ist mit dem Szenario, wo eine ** signifikante Anzahl ** von HTTP-Anfragen in einem ** einzigen ** HTTP serviert Verbindung? Für dieses Szenario kann ich mir vorstellen, dass die Three-per-Request-Strategie aufgrund des Thread-Pool-Verwaltungsaufwands viel Serverlast verursacht, während die Verbindung pro Anfrage-Strategie diesen Overhead nicht hätte. – Abdull

2

HTTP 1.1 - hat die Unterstützung für persistente Verbindungen, die die gleiche HTTP-Verbindung empfangen/gesendet werden, können mehr als eine Anforderung/Antwort bedeutet. Um also die Anfragen auszuführen, die mit der gleichen Verbindung parallel empfangen wurden, wird für jede Anforderung ein neuer Thread erstellt.

HTTP 1.0 - In dieser Version wurde nur eine Anforderung über die Verbindung empfangen und die Verbindung wurde nach dem Senden der Antwort geschlossen. Daher wurde nur ein Thread für eine Verbindung erstellt.

2

Thread per connection ist das Konzept der Wiederverwendung derselben HTTP Connection von multiple requests (keep-alive).

Thread per request wird ein Thread für each request aus einem client .Server erstellen kann eine Anzahl von threads gemäß request erstellen.

+0

Um anderen zu verdeutlichen, wird keep-alive nicht unbedingt einen Thread für die gesamte Verbindung zuweisen, zum Beispiel wenn er gegen einen Servlet-Container erstellt wird. Das ist der Unterschied zwischen Keep-Alive und TPC. – tunesmith

0

Thread pro Anfrage sollte besser sein, da es Threads wiederverwendet, während einige Client im Leerlauf sind. Wenn Sie viele gleichzeitige Benutzer haben, könnten sie mit einer geringeren Anzahl von Threads bedient werden und die gleiche Anzahl von Threads wäre teurer. Es gibt noch eine weitere Überlegung - wir wissen nicht, ob der Benutzer noch mit der Anwendung arbeitet, also können wir nicht wissen, wann wir einen Thread zerstören müssen. Mit einem Thread pro Anfrage-Mechanismus verwenden wir nur einen Thread-Pool.

+0

Verwendet es Thread-Pool oder erstellt neue Threads und verbindet die alten? – LtWorf

+0

Laichen eines neuen Threads ist sehr teuer Operation. Ich nehme an, dass jede adäquate Implementierung Threads über den Pool wiederverwendet. – Mikhail

+0

Ich weiß, es ist teuer, darum habe ich gefragt. Ohne Thread-Pool ist die Verwendung eines Threads pro Anfrage viel teurer als die Verwendung eines Threads pro Verbindung. Und Annahmen sind schlecht, darum habe ich gefragt. – LtWorf

1

Thread pro Anfrage erstellt einen Thread für jede HTTP-Anforderung, die der Server empfängt.

Thread pro Verbindung die gleiche HTTP-Verbindung von mehreren Anforderungen Wiederverwendung (Keep-Alive) .AKA HTTP persistent connection aber bitte beachten Sie, dass dies nur unterstützt von HTTP 1.1

Thread pro Anfrage ist schneller als die meisten Web-Container Verwendung Thread-Pooling

Die Anzahl der maximalen parallelen Verbindungen, die Sie für die Anzahl der Kerne auf Ihrem Server festlegen sollten. Mehr Kerne => mehr parallele Threads.

Sehen Sie hier, wie zu konfigurieren ... Tomcat 6: http://tomcat.apache.org/tomcat-6.0-doc/config/executor.html

Tomcat 7: http://tomcat.apache.org/tomcat-7.0-doc/config/executor.html

Beispiel

Verwandte Themen