Momentan spiel ich etwas mit dem MVC3 RC rum. Ein neues Feature, welches allerdings kaum groß verkündet wurde, ist die Einführung eines SessionState Behaviour um z.B. ein Controller gänzlich Stateless und Sessionless zu machen. Wie das geht, was die Fallen daran sind und wofür man es evtl. braucht habe ich mit meinem gesunden Halbwissen mal zusammengeschrieben :)
Sessionless? Mein Versuchsaufbau
Meine Demoanwendung besteht aus zwei Controllern. Der eine ist "sessionless” gemacht. Dazu gibt es noch zwei Views für die Ausgabe. Ansonsten entspricht die MVC App einer "Empty Website” (bis auf das Routing, was im Standardfall nun zum SessionController leitet.
[ControllerSessionState(SessionStateBehavior.Disabled)] public class SessionLessController : Controller { // // GET: /SessionLess/ public ActionResult Index() { Thread.Sleep(1000); ViewModel.Session = this.ControllerContext.HttpContext.Session; return View(ViewModel); } }
Am interessantesten ist hier eigentlich das ControllerSessionState Attribute (Achtung: Irgendwo hatte ich gelesen, dass die noch in der Final anders benannt werden soll - einfach dann mal danach suchen ;) ).
Über das Attribut kann auf Controller-Ebene auf das Verhalten des Sessionstates Einfluss genommen werden:
Gänzlich ausschalten kann man es über "Disable”, dann ist die Session "null”.
Was gibt es für Dinge zu beachten?
Auf den ersten Blick: Man kann nicht auf die Session zugreifen. Das heisst man greift z.B. um den User wiederzuerkennen auf das FormsAuth Cookie etc. zurück. Sobald man etwas in das "TempData” schreiben will, bekommt man eine Exception "The SessionStateTempDataProvider class requires session state to be enabled”. Wenn man also Daten von Controller A zum Controller B irgendwie weiterschleifen möchte, müsste das z.B. in einem Cookie erfolgen. Es soll allerdings in den MVC Futures ein CookieStateTempDataProvider geben.
Wofür soll das gut sein?
Gute Frage, in diesem Stackoverflow Post hab ich eine interessante Begründung gefunden:
The release notes cover this more (you can download them from the download link above). Session state is designed so that only one request from a particular user/session occurs at a time. So if you have a page that has multiple AJAX callbacks happening at once they will be processed in serial fashion on the server. Going session-less means that they would execute in parallel.
Auch hier wird es recht gut erklärt: Concurrent Requests In ASP.NET MVC
Hat es auf die Performance Auswirkungen?
Ich hab mal etwas rumexperimentiert mit den Visual Studio 2010 Test Tools und hab ohne das Thread.Sleep im Controller ein WebPerformanceTest mit 1000 Iterationen jeweils auf den Sessionless und einmal auf den "normalen” Controller losgelassen.
Achtung: Ich hab noch nie wirklich was mit den WebTest Tools von VS2010 gemacht, daher können meine Ergebnisse auch total banal und nicht richtig sein.
Die Tests liefen auf meinem Macbook in einer VM. Die WebApp wurde im IIS7 gehostet - die Werte spiegel also keine Performancegeschichten eines IIS wieder.
Ergebnisse bei 1000 Wiederholungen (also 1000 mal die Seite aufrufen) und KEIN Thread.Sleep:
Durchgang | SessionLess (Zeit in Sek) | Session (Zeit in Sek) |
1 | 5,70 | 6,17 |
2 | 5,15 | 6,21 |
3 | 5,28 | 5,15 |
4 | 5,16 | 6,74 |
5 | 5,13 | 5,54 |
6 | 6,68 | 5,50 |
7 | 5,12 | 5,17 |
8 | 5,30 | 5,66 |
9 | 6,28 | 5,30 |
10 | 4,98 | 5,27 |
Hier und da gibt es ein paar Ausreißer auf beiden Seiten, jedoch scheint der Sessionless Controller etwas schneller zu sein.
Ich hab noch einen anderen Test gemacht (einen so genannten "LoadTest”), die Zahlen daraus sind ähnlich. Am Rande erwähnt: Sehr interessantes Tool, da müsste man sich näher damit befassen. Ich geh aber nicht weiter darauf ein.
Fazit
In Hinblick auf Skalierbarkeit und "große” Webapplikationen ist es vielleicht interessant sich mit dem Thema näher zu befassen. Für eine 0815 Seite sehe ich allerdings da keinen richtigen Bedarf. Etwas in die Session zu packen ist manchmal recht bequem und z.B. bei Wizard ähnlichen Anwendungen sehr nett. Natürlich darf da kein Wildwuchs entstehen. Ich kann mich bei meiner Einschätzung aber auch täuschen ;)
[ Download Sample ] (Achtung: Für das Testprojekt ist evtl. eine höherwertige Visual Studio Version notwendig)