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.
http://stackoverflow.com/questions/7457190/how-threads-allocated-to-handle-servlet-request - duplizieren? – Mikhail