ASP.NET (MVC) Outputcache und gleichzeitige Anfragen

8

Nehmen wir an, theoretisch, ich habe eine Seite / Controller-Aktion in meiner Website, die einige sehr schwere Sachen macht. Es dauert ungefähr 10 Sekunden, um den Vorgang abzuschließen.

Nun benutze ich den Outputcache-Mechanismus von .NET, um ihn für 15 Minuten zwischenzuspeichern (zum Beispiel benutze ich [OutputCache(Duration = 900)] ) Was passiert, wenn nach 15 Minuten der Cache abgelaufen ist und 100 Benutzer die Seite innerhalb dieser 10 Sekunden erneut anfordern das es braucht, um die schwere Verarbeitung zu tun?

  1. Das schwere Zeug wird nur beim ersten Mal gemacht, und es gibt einen Sperrmechanismus, so dass die anderen 99 Benutzer das Cache-Ergebnis erhalten
  2. Das schwere Zeug ist 100 Mal fertig (und der Server ist verkrüppelt, da es bis zu 100 * 10 Sekunden dauern kann)

Einfache Frage vielleicht, aber ich bin mir nicht 100% sicher. Ich hoffe, es ist die Nummer eins, obwohl: -)

Danke!

    
Razzie 29.01.2010, 14:15
quelle

5 Antworten

4

Nun, es hängt davon ab, wie Sie IIS konfiguriert haben. Wenn Sie weniger als 100 Worker-Threads (sagen wir 50) haben, wird das "schwere Zeug" 50 mal ausgeführt, wodurch Ihr Server lahmgelegt wird und die verbleibenden 50 Anfragen aus dem Cache ausgeführt werden.

Aber nein, es gibt keinen "Sperrmechanismus" für ein zwischengespeichertes Aktionsergebnis; das wäre größtenteils kontraproduktiv.

Bearbeiten : Ich glaube, dass das stimmt, aber Nicks Tests sagen etwas anderes, und ich habe jetzt keine Zeit zum Testen. Versuch es selber! Der Rest der Antwort hängt jedoch nicht von dem oben Gesagten ab, und ich denke, es ist wichtiger.

Im Allgemeinen sollte jedoch keine zwischengespeicherte Web-Anfrage 10 Sekunden dauern. Wenn ich in deinen Schuhen wäre, würde ich mir irgendwie den harten Teil der Anfrage vorrechnen. Sie können das Ergebnis der Aktion trotzdem zwischenspeichern, wenn Sie den HTML-Code zwischenspeichern möchten, aber Ihr Problem scheint etwas größer zu sein.

Sie möchten auch betrachte asynchrone Controller . Beachten Sie schließlich, dass IIS und ASP.NET MVC diese schwere Berechnung nicht sperren können. Wenn Sie asynchrone Controller in Kombination mit einer Sperre für die Berechnung verwenden, erhalten Sie effektiv das von Ihnen geforderte Verhalten. Ich kann nicht wirklich sagen, ob das die beste Lösung ist, ohne mehr darüber zu wissen, was du tust.

    
Craig Stuntz 29.01.2010, 14:26
quelle
3

Es scheint hier zu sperren, einen einfachen Test zu machen:

%Vor%

Die erste Seite trifft dort einen Haltepunkt, obwohl sie ruht ... keine andere Anforderung trifft einen Haltepunkt in der Page_Load-Methode ... sie wartet auf den ersten Haltepunkt und gibt dieses Ergebnis an alle zurück, die dies angefordert haben Seite.

Hinweis: Dies war in einem Webformular-Szenario einfacher zu testen, aber da dies ein gemeinsamer Aspekt der Frameworks ist, können Sie denselben Test in MVC mit dem gleichen Ergebnis durchführen.

Hier ist ein alternativer Test:

%Vor%

Alle Seiten, die in die Warteschlange eingereiht werden, während die erste Anfrage in den Ruhezustand geht, haben die gleiche Ausgabe.

    
Nick Craver 29.01.2010 14:31
quelle
3

Alte Frage, aber ich bin auf dieses Problem gestoßen und habe einige Nachforschungen angestellt.

Beispielcode:

%Vor%

Führen Sie es in einem Browser aus und es scheint zu sperren und zu warten.

Führen Sie es in verschiedenen Browsern aus (ich habe IE und Firefox getestet) und die Anfragen werden nicht gehalten.

Das "richtige" Verhalten hat also mehr damit zu tun, welchen Browser Sie verwenden als die Funktion in IIS.

Bearbeiten: Um zu klären - Keine Sperre. Der Server wird von allen Anfragen betroffen, die es schaffen, sich einzuloggen, bevor das erste Ergebnis zwischengespeichert wird, was bei schweren Anfragen möglicherweise zu einem schweren Treffer auf dem Server führt. (Oder wenn Sie ein externes System aufrufen, könnte dieses System heruntergefahren werden, wenn Ihr Server viele Anfragen bearbeitet ...)

    
Mats Nilsson 11.12.2012 11:46
quelle
1

Ich habe einen kleinen Test gemacht, der helfen könnte. Ich glaube, was ich entdeckt habe, ist, dass die nicht zwischengespeicherten Anfragen nicht blockiert werden, und jede Anfrage, die hereinkommt, während der Cache abgelaufen ist und bevor die Aufgabe beendet wird, löst diese Aufgabe ebenfalls aus.

Zum Beispiel dauert der folgende Code ungefähr 6-9 Sekunden auf meinem System mit Cassini. Wenn Sie zwei Anfragen im Abstand von ca. 2 Sekunden (d. H. Zwei Browser-Tabs) senden, erhalten beide eindeutige Ergebnisse. Die letzte zu beendende Anforderung ist auch die Antwort, die für nachfolgende Anforderungen zwischengespeichert wird.

%Vor%     
Andrew 24.05.2011 20:42
quelle
0

Sie sollten diese Informationen überprüfen hier : "Sie haben einen einzelnen Client, der mehrere gleichzeitige Anforderungen an den Server stellt. Standardmäßig werden diese Anforderungen serialisiert."

Wenn also die gleichzeitige Anforderung von dem einzelnen Client serialisiert wird, wird die nachfolgende Anforderung den Cache verwenden. Das erklären einige Verhaltensweisen in einigen Antworten oben (@ Mats-Nilsson und @ Nick-Craver)

Der Kontext, den Sie uns gezeigt haben, besteht aus mehreren Benutzern, die gleichzeitig auf Ihren Server treffen und Ihr Server wird beschäftigt sein, bis mindestens eine Anfrage abgeschlossen ist und der Ausgabe-Cache erstellt wurde und für die nächste Anfrage verwendet wird. Wenn Sie also mehrere Benutzer serialisieren möchten, die dieselbe Ressource anfordern, müssen wir verstehen, wie die serialisierte Anforderung für einen einzelnen Benutzer funktioniert. Willst du das?

    
mqueirozcorreia 21.01.2016 13:04
quelle