Ich habe gerade herausgefunden, warum alle ASP.Net-Websites langsam sind, und ich versuche herauszufinden, was ich dagegen tun soll

275

Ich habe gerade festgestellt, dass jede Anforderung in einer ASP.Net-Webanwendung zu Beginn einer Anforderung eine Sitzungssperre erhält und diese am Ende der Anforderung freigibt!

Falls die Auswirkungen auf Sie verloren gehen, wie es zunächst für mich der Fall war, bedeutet dies im Grunde Folgendes:

  • Immer wenn das Laden einer ASP.Net-Webseite lange dauert (möglicherweise aufgrund eines langsamen Datenbankaufrufs oder was auch immer) und der Benutzer entscheidet, dass er zu einer anderen Seite navigieren möchte, weil er das Warten satt hat, KÖNNEN SIE NICHT! Die ASP.Net-Sitzungssperre zwingt die neue Seitenanforderung zu warten, bis die ursprüngliche Anforderung schmerzhaft langsam geladen wurde. Arrrgh.

  • Immer wenn ein UpdatePanel langsam geladen wird und der Benutzer beschließt, zu einer anderen Seite zu navigieren, bevor das UpdatePanel die Aktualisierung abgeschlossen hat ... SIE KÖNNEN NICHT! Die ASP.net-Sitzungssperre zwingt die neue Seitenanforderung zu warten, bis die ursprüngliche Anforderung schmerzhaft schmerzhaft geladen wurde. Double Arrrgh!

Welche Möglichkeiten gibt es? Bisher habe ich mir Folgendes ausgedacht:

  • Implementieren Sie einen benutzerdefinierten SessionStateDataStore, den ASP.Net unterstützt. Ich habe nicht zu viele gefunden, um sie zu kopieren, und es scheint ein hohes Risiko zu sein und leicht durcheinander zu bringen.
  • Behalten Sie den Überblick über alle laufenden Anforderungen. Wenn eine Anforderung vom selben Benutzer eingeht, brechen Sie die ursprüngliche Anforderung ab. Scheint irgendwie extrem, aber es würde funktionieren (glaube ich).
  • Verwenden Sie keine Sitzung! Wenn ich einen Status für den Benutzer benötige, kann ich stattdessen einfach Cache und Schlüsselelemente für den authentifizierten Benutzernamen oder ähnliches verwenden. Scheint wieder irgendwie extrem.

Ich kann wirklich nicht glauben, dass das ASP.Net Microsoft-Team bei Version 4.0 einen so großen Leistungsengpass im Framework hinterlassen hätte! Vermisse ich etwas Offensichtliches? Wie schwierig wäre es, eine ThreadSafe-Sammlung für die Sitzung zu verwenden?

James
quelle
40
Sie erkennen, dass diese Site auf .NET erstellt wurde. Das heißt, ich denke, es skaliert ganz gut.
Wheaties
7
OK, also war ich mit meinem Titel ein wenig scherzhaft. Trotzdem ist meiner Meinung nach die Leistungsbeeinträchtigung, die die sofort einsatzbereite Implementierung der Sitzung mit sich bringt, verblüffend. Ich wette auch, dass die Stack Overflow-Leute ein gutes Stück hochgradig kundenspezifischer Entwicklung leisten mussten, um die Leistung und Skalierbarkeit zu erzielen, die sie erreicht haben - und ein großes Lob an sie. Schließlich ist Stack Overflow eine MVC-APP, keine WebForms, was meiner Meinung nach hilfreich ist (obwohl dies zugegebenermaßen immer noch dieselbe Sitzungsinfrastruktur verwendet).
James
4
Wenn Joel Mueller Ihnen die Informationen zur Behebung Ihres Problems gegeben hat, warum haben Sie seine Antwort nicht als die richtige Antwort markiert? Nur ein Gedanke.
Ars265
1
@ ars265 - Joel Muller lieferte viele gute Informationen, und ich wollte ihm dafür danken. Letztendlich bin ich jedoch einen anderen Weg gegangen als den in seinem Beitrag vorgeschlagenen. Markieren Sie daher einen anderen Beitrag als Antwort.
James

Antworten:

201

Wenn Ihre Seite keine Sitzungsvariablen ändert, können Sie den größten Teil dieser Sperre deaktivieren.

<% @Page EnableSessionState="ReadOnly" %>

Wenn Ihre Seite keine Sitzungsvariablen liest, können Sie diese Sperre für diese Seite vollständig deaktivieren.

<% @Page EnableSessionState="False" %>

Wenn keine Ihrer Seiten Sitzungsvariablen verwendet, deaktivieren Sie einfach den Sitzungsstatus in der Datei web.config.

<sessionState mode="Off" />

Ich bin gespannt, was würde "eine ThreadSafe-Sammlung" Ihrer Meinung nach tun, um threadsicher zu werden, wenn keine Sperren verwendet werden?

Bearbeiten: Ich sollte wahrscheinlich erklären, was ich mit "Deaktivieren des größten Teils dieser Sperre" meine. Eine beliebige Anzahl von Seiten mit schreibgeschützter Sitzung oder ohne Sitzung kann für eine bestimmte Sitzung gleichzeitig verarbeitet werden, ohne sich gegenseitig zu blockieren. Eine Lese- / Schreibsitzungsseite kann jedoch erst mit der Verarbeitung beginnen, wenn alle schreibgeschützten Anforderungen abgeschlossen sind. Während der Ausführung muss sie exklusiven Zugriff auf die Sitzung dieses Benutzers haben, um die Konsistenz aufrechtzuerhalten. Das Sperren einzelner Werte würde nicht funktionieren, denn was ist, wenn eine Seite eine Reihe verwandter Werte als Gruppe ändert? Wie würden Sie sicherstellen, dass andere Seiten, die gleichzeitig ausgeführt werden, eine konsistente Ansicht der Sitzungsvariablen des Benutzers erhalten?

Ich würde vorschlagen, dass Sie versuchen, die Änderung von Sitzungsvariablen zu minimieren, sobald sie festgelegt wurden, wenn dies möglich ist. Auf diese Weise können Sie den Großteil Ihrer Seiten schreibgeschützt machen, wodurch sich die Wahrscheinlichkeit erhöht, dass sich mehrere gleichzeitige Anforderungen desselben Benutzers nicht gegenseitig blockieren.

Joel Mueller
quelle
2
Hallo Joel, danke für deine Zeit bei dieser Antwort. Dies sind einige gute Vorschläge und einige Denkanstöße. Ich verstehe Ihre Argumentation nicht, dass alle Werte für eine Sitzung ausschließlich für die gesamte Anforderung gesperrt sein müssen. ASP.Net-Cache-Werte können jederzeit von jedem Thread geändert werden. Warum sollte dies für die Sitzung anders sein? Nebenbei bemerkt - ein Problem, das ich mit der schreibgeschützten Option habe, ist, dass ein Entwickler, der der Sitzung im schreibgeschützten Modus einen Wert hinzufügt, im Stillen fehlschlägt (keine Ausnahme). Tatsächlich behält es den Wert für den Rest der Anfrage bei - aber nicht darüber hinaus.
James
5
@James - Ich rate nur zu den Motivationen der Designer hier, aber ich stelle mir vor, dass es üblicher ist, dass mehrere Werte in einer Sitzung eines einzelnen Benutzers voneinander abhängen, als in einem Cache, der wegen mangelnder Verwendung oder geringer Anzahl gelöscht werden kann. Speichergründe jederzeit. Wenn auf einer Seite 4 verwandte Sitzungsvariablen festgelegt sind und auf einer anderen Seite diese gelesen werden, nachdem nur zwei geändert wurden, kann dies leicht zu sehr schwer zu diagnostizierenden Fehlern führen. Ich kann mir vorstellen, dass die Designer aus diesem Grund "den aktuellen Status einer Benutzersitzung" als eine Einheit für Sperrzwecke betrachten.
Joel Mueller
2
Entwickeln Sie also ein System, das sich an Programmierer mit dem kleinsten gemeinsamen Nenner richtet, die das Sperren nicht herausfinden können? Ist der Zweck, Webfarmen zu aktivieren, die einen Sitzungsspeicher für IIS-Instanzen gemeinsam nutzen? Können Sie ein Beispiel für etwas geben, das Sie in einer Sitzungsvariablen speichern würden? Mir fällt nichts ein.
Jason Goemaat
2
Ja, das ist einer der Zwecke. Überdenken Sie die verschiedenen Szenarien, wenn Lastausgleich und Redundanz in der Infrastruktur implementiert sind. Wenn der Benutzer auf der Webseite arbeitet, dh Daten für beispielsweise 5 Minuten in das Formular eingibt, stürzt etwas in der Webfarm ab - die Stromquelle eines Knotens geht auf - der Benutzer sollte dies NICHT bemerken. Er kann nicht aus der Sitzung geworfen werden, nur weil seine Sitzung verloren gegangen ist, nur weil sein Arbeitsprozess nicht mehr existiert. Dies bedeutet , dass perfektes Wuchten / Redundanz zu handhaben , müssen die Sitzungen vom Arbeiter Knoten .. externalisiert werden
quetzalcoatl
6
Eine weitere nützliche <pages enableSessionState="ReadOnly" />Option zum Deaktivieren ist web.config. Verwenden Sie @Page, um das Schreiben nur auf bestimmten Seiten zu aktivieren.
MattW
84

OK, so große Requisiten an Joel Muller für all seine Beiträge. Meine ultimative Lösung bestand darin, das am Ende dieses MSDN-Artikels beschriebene benutzerdefinierte SessionStateModule zu verwenden:

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx

Das war:

  • Sehr schnell zu implementieren (schien einfacher zu sein als den Weg des Anbieters zu gehen)
  • Verwendete einen Großteil der standardmäßigen ASP.Net-Sitzungsbehandlung (über die SessionStateUtility-Klasse).

Dies hat einen RIESIGEN Unterschied zum Gefühl der "Schnelligkeit" unserer Anwendung gemacht. Ich kann immer noch nicht glauben, dass die benutzerdefinierte Implementierung von ASP.Net Session die Sitzung für die gesamte Anforderung sperrt. Dies verleiht Websites eine so große Trägheit. Gemessen an der Menge an Online-Recherchen, die ich durchführen musste (und an Gesprächen mit mehreren wirklich erfahrenen ASP.Net-Entwicklern), haben viele Menschen dieses Problem erlebt, aber nur sehr wenige Menschen sind jemals der Sache auf den Grund gegangen. Vielleicht schreibe ich einen Brief an Scott Gu ...

Ich hoffe das hilft ein paar Leuten da draußen!

James
quelle
19
Diese Referenz ist ein interessanter Fund, aber ich muss Sie in einigen Punkten warnen - der Beispielcode weist einige Probleme auf: Erstens ReaderWriterLockwurde er zugunsten von abgelehnt ReaderWriterLockSlim- Sie sollten ihn stattdessen verwenden. Zweitens lock (typeof(...))wurde auch veraltet - Sie sollten stattdessen eine private statische Objektinstanz sperren. Drittens ist der Ausdruck "Diese Anwendung verhindert nicht, dass gleichzeitige Webanforderungen dieselbe Sitzungskennung verwenden" eine Warnung und keine Funktion.
Joel Mueller
3
Ich denke, Sie können dies zum Laufen bringen, aber Sie müssen die Verwendung SessionStateItemCollectionim Beispielcode durch eine thread-sichere Klasse (möglicherweise basierend auf ConcurrentDictionary) ersetzen, wenn Sie schwer zu reproduzierende Fehler unter Last vermeiden möchten.
Joel Mueller
3
Ich habe mich nur etwas genauer damit befasst und ISessionStateItemCollectionverlange leider, dass die KeysEigenschaft vom Typ ist System.Collections.Specialized.NameObjectCollectionBase.KeysCollection- der keine öffentlichen Konstrukteure hat. Danke Jungs. Das ist sehr praktisch.
Joel Mueller
2
OK, ich glaube, ich habe endlich eine vollständige threadsichere, nicht lesbare Sperrimplementierung der Sitzungsarbeit. Die letzten Schritte umfassten die Implementierung einer benutzerdefinierten threadsicheren SessionStateItem-Auflistung, die auf dem MDSN-Artikel basierte, auf den im obigen Kommentar verwiesen wurde. Das letzte Puzzleteil dabei war die Erstellung eines threadsicheren Enumerators basierend auf diesem großartigen Artikel: codeproject.com/KB/cs/safe_enumerable.aspx .
James
26
James - offensichtlich ist dies ein ziemlich altes Thema, aber ich habe mich gefragt, ob Sie Ihre ultimative Lösung teilen konnten. Ich habe versucht, den obigen Kommentarthread zu verwenden, konnte aber bisher keine funktionierende Lösung finden. Ich bin mir ziemlich sicher, dass unsere eingeschränkte Nutzung der Sitzung nichts Grundlegendes enthält, das ein Sperren erfordern würde.
bsiegel
31

Ich habe angefangen, das AngiesList.Redis.RedisSessionStateModule zu verwenden . Abgesehen von der Verwendung des (sehr schnellen) Redis-Servers für die Speicherung (ich verwende den Windows-Port - obwohl es auch einen MSOpenTech-Port gibt ) wird die Sitzung absolut nicht gesperrt .

Meiner Meinung nach ist dies kein Problem, wenn Ihre Anwendung angemessen strukturiert ist. Wenn Sie im Rahmen der Sitzung tatsächlich gesperrte, konsistente Daten benötigen, sollten Sie selbst eine Sperr- / Parallelitätsprüfung durchführen.

Die Entscheidung von MS, dass jede ASP.NET-Sitzung standardmäßig gesperrt werden sollte, um mit schlechtem Anwendungsdesign umzugehen, ist meiner Meinung nach eine schlechte Entscheidung. Vor allem, weil es den Anschein hat, als hätten die meisten Entwickler nicht einmal bemerkt, dass Sitzungen gesperrt waren, geschweige denn, dass Apps anscheinend so strukturiert sein müssen, dass Sie den Status einer schreibgeschützten Sitzung so weit wie möglich festlegen können (Opt-out, wo möglich). .

Gregmac
quelle
Dein GitHub-Link scheint 404-tot zu sein. Bibliotheken.io/github/angieslist/AL-Redis scheint die neue URL zu sein?
Uwe Keim
Es sieht so aus, als wollte der Autor die Bibliothek sogar über den zweiten Link entfernen. Ich würde zögern, eine verlassene Bibliothek zu verwenden, aber hier gibt es eine Abzweigung: github.com/PrintFleet/AL-Redis und eine alternative Bibliothek, die von hier aus verlinkt ist: stackoverflow.com/a/10979369/12534
Christian Davén
21

Ich habe eine Bibliothek basierend auf Links in diesem Thread vorbereitet. Es werden die Beispiele von MSDN und CodeProject verwendet. Danke an James.

Ich habe auch Änderungen vorgenommen, die von Joel Mueller empfohlen wurden.

Code ist hier:

https://github.com/dermeister0/LockFreeSessionState

HashTable-Modul:

Install-Package Heavysoft.LockFreeSessionState.HashTable

ScaleOut StateServer-Modul:

Install-Package Heavysoft.LockFreeSessionState.Soss

Benutzerdefiniertes Modul:

Install-Package Heavysoft.LockFreeSessionState.Common

Wenn Sie die Unterstützung von Memcached oder Redis implementieren möchten, installieren Sie dieses Paket. Erben Sie dann die LockFreeSessionStateModule- Klasse und implementieren Sie abstrakte Methoden.

Der Code wurde noch nicht in der Produktion getestet. Außerdem muss die Fehlerbehandlung verbessert werden. Ausnahmen werden in der aktuellen Implementierung nicht berücksichtigt.

Einige sperrfreie Sitzungsanbieter, die Redis verwenden:

Der_Meister
quelle
Es erfordert Bibliotheken aus der ScaleOut-Lösung, die nicht kostenlos ist?
Hoàng Long
1
Ja, ich habe die Implementierung nur für SOSS erstellt. Sie können die genannten Redis-Sitzungsanbieter verwenden, es ist kostenlos.
Der_Meister
Vielleicht hat Hoàng Long den Punkt übersehen, dass Sie zwischen der speicherinternen HashTable-Implementierung und ScaleOut StateServer wählen können.
David De Sloovere
Vielen Dank für Ihren Beitrag :) Ich werde versuchen, herauszufinden, wie sich dies auf die wenigen Anwendungsfälle auswirkt, die wir mit SESSION haben.
Agustin Garzon
Da viele Leute erwähnt haben, dass ein bestimmtes Element in der Sitzung gesperrt wird, kann es sinnvoll sein, darauf hinzuweisen, dass die Backing-Implementierung einen gemeinsamen Verweis auf den Sitzungswert über get-Aufrufe zurückgeben muss, um das Sperren (und sogar) zu aktivieren das funktioniert nicht mit Servern mit Lastenausgleich). Abhängig davon, wie Sie den Sitzungsstatus verwenden, besteht hier das Potenzial für Rennbedingungen. Außerdem scheint es mir, dass Ihre Implementierung Sperren enthält, die eigentlich nichts bewirken, da sie nur einen einzigen Lese- oder Schreibaufruf umschließen (korrigieren Sie mich, wenn ich hier falsch liege).
nw.
11

Ich denke, Sie haben zwei Ansätze, es sei denn, Ihre Bewerbung hat spezielle Anforderungen:

  1. Verwenden Sie die Sitzung überhaupt nicht
  2. Verwenden Sie die Sitzung unverändert und führen Sie die Feinabstimmung wie angegeben durch.

Die Sitzung ist nicht nur threadsicher, sondern auch zustandsicher, sodass Sie wissen, dass sich jede Sitzungsvariable bis zum Abschluss der aktuellen Anforderung nicht von einer anderen aktiven Anforderung ändert. Dazu müssen Sie sicherstellen, dass die Sitzung gesperrt wird, bis die aktuelle Anforderung abgeschlossen ist.

Sie können ein sitzungsähnliches Verhalten auf viele Arten erstellen. Wenn die aktuelle Sitzung jedoch nicht gesperrt wird, handelt es sich nicht um eine Sitzung.

Für die spezifischen Probleme, die Sie erwähnt haben, sollten Sie HttpContext.Current.Response.IsClientConnected überprüfen . Dies kann nützlich sein, um unnötige Ausführungen und Wartezeiten auf dem Client zu verhindern, obwohl dieses Problem nicht vollständig gelöst werden kann, da dies nur auf Pool-Weise und nicht asynchron verwendet werden kann.

George Mavritsakis
quelle
10

Wenn Sie die aktualisierte Version Microsoft.Web.RedisSessionStateProvider(ab 3.0.2) verwenden, können Sie diese zu Ihrer hinzufügen web.config, um gleichzeitige Sitzungen zuzulassen.

<appSettings>
    <add key="aspnet:AllowConcurrentRequestsPerSession" value="true"/>
</appSettings>

Quelle

rabz100
quelle
Ich bin mir nicht sicher, warum dies bei 0 war. +1. Sehr hilfreich.
Pangamma
Funktioniert dies im App-Pool im klassischen Modus? github.com/Azure/aspnet-redis-providers/issues/123
Rusty
Funktioniert dies mit dem Standard-Dienstanbieter inProc oder Session State?
Nick Chan Abdullah
Beachten Sie, dass das Poster auf RedisSessionStateprovider verweist, aber möglicherweise auch mit diesen neueren AspNetSessionState Async-Anbietern (für SQL und Cosmos) funktioniert, da es auch in der Dokumentation enthalten ist: github.com/aspnet/AspNetSessionState Ich vermute, dass es in funktionieren würde classicmode Wenn der SessionStateProvider bereits im klassischen Modus arbeitet, geschieht der Sitzungsstatus wahrscheinlich in ASP.Net (nicht in IIS). Mit InProc funktioniert es möglicherweise nicht, ist aber weniger problematisch, da es ein Problem mit Ressourcenkonflikten löst, das bei Out-Proc-Szenarien eine größere Rolle spielt.
Madamission
4

Für ASPNET MVC haben wir Folgendes getan:

  1. Standardmäßig SessionStateBehavior.ReadOnlywird die Aktion aller Controller durch Überschreiben festgelegtDefaultControllerFactory
  2. Markieren Sie bei Controller-Aktionen, die in den Sitzungsstatus geschrieben werden müssen, das Attribut, auf das es festgelegt werden soll SessionStateBehavior.Required

Erstellen Sie eine benutzerdefinierte ControllerFactory und überschreiben Sie diese GetControllerSessionBehavior.

    protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)
    {
        var DefaultSessionStateBehaviour = SessionStateBehaviour.ReadOnly;

        if (controllerType == null)
            return DefaultSessionStateBehaviour;

        var isRequireSessionWrite =
            controllerType.GetCustomAttributes<AcquireSessionLock>(inherit: true).FirstOrDefault() != null;

        if (isRequireSessionWrite)
            return SessionStateBehavior.Required;

        var actionName = requestContext.RouteData.Values["action"].ToString();
        MethodInfo actionMethodInfo;

        try
        {
            actionMethodInfo = controllerType.GetMethod(actionName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
        }
        catch (AmbiguousMatchException)
        {
            var httpRequestTypeAttr = GetHttpRequestTypeAttr(requestContext.HttpContext.Request.HttpMethod);

            actionMethodInfo =
                controllerType.GetMethods().FirstOrDefault(
                    mi => mi.Name.Equals(actionName, StringComparison.CurrentCultureIgnoreCase) && mi.GetCustomAttributes(httpRequestTypeAttr, false).Length > 0);
        }

        if (actionMethodInfo == null)
            return DefaultSessionStateBehaviour;

        isRequireSessionWrite = actionMethodInfo.GetCustomAttributes<AcquireSessionLock>(inherit: false).FirstOrDefault() != null;

         return isRequireSessionWrite ? SessionStateBehavior.Required : DefaultSessionStateBehaviour;
    }

    private static Type GetHttpRequestTypeAttr(string httpMethod) 
    {
        switch (httpMethod)
        {
            case "GET":
                return typeof(HttpGetAttribute);
            case "POST":
                return typeof(HttpPostAttribute);
            case "PUT":
                return typeof(HttpPutAttribute);
            case "DELETE":
                return typeof(HttpDeleteAttribute);
            case "HEAD":
                return typeof(HttpHeadAttribute);
            case "PATCH":
                return typeof(HttpPatchAttribute);
            case "OPTIONS":
                return typeof(HttpOptionsAttribute);
        }

        throw new NotSupportedException("unable to determine http method");
    }

AcquireSessionLockAttribute

[AttributeUsage(AttributeTargets.Method)]
public sealed class AcquireSessionLock : Attribute
{ }

Schließen Sie die erstellte Controller-Factory an global.asax.cs

ControllerBuilder.Current.SetControllerFactory(typeof(DefaultReadOnlySessionStateControllerFactory));

Jetzt können wir beide read-onlyund den read-writeSitzungsstatus in einem einzigen haben Controller.

public class TestController : Controller 
{
    [AcquireSessionLock]
    public ActionResult WriteSession()
    {
        var timeNow = DateTimeOffset.UtcNow.ToString();
        Session["key"] = timeNow;
        return Json(timeNow, JsonRequestBehavior.AllowGet);
    }

    public ActionResult ReadSession()
    {
        var timeNow = Session["key"];
        return Json(timeNow ?? "empty", JsonRequestBehavior.AllowGet);
    }
}

Hinweis: Der ASPNET-Sitzungsstatus kann auch im schreibgeschützten Modus noch beschrieben werden und löst keine Ausnahme aus (er wird nur nicht gesperrt, um die Konsistenz zu gewährleisten). Daher müssen wir darauf achten, AcquireSessionLockdie Aktionen des Controllers zu markieren , die das Schreiben des Sitzungsstatus erfordern.

Misterhex
quelle
3

Wenn Sie den Sitzungsstatus eines Controllers als schreibgeschützt oder deaktiviert markieren, wird das Problem behoben .

Sie können einen Controller mit dem folgenden Attribut dekorieren, um ihn als schreibgeschützt zu markieren:

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]

Die Aufzählung System.Web.SessionState.SessionStateBehavior hat die folgenden Werte:

  • Standard
  • Behindert
  • Schreibgeschützt
  • Erforderlich
Michael King
quelle
0

Nur um jemandem bei diesem Problem zu helfen (Sperren von Anforderungen, wenn eine andere aus derselben Sitzung ausgeführt wird) ...

Heute habe ich begonnen, dieses Problem zu lösen, und nach einigen Stunden Recherche habe ich es gelöst, indem ich die Session_StartMethode (auch wenn sie leer ist) aus Global.asax entfernt habe Datei .

Dies funktioniert in allen Projekten, die ich getestet habe.

graduenz
quelle
IDK, für welche Art von Projekt dies war, aber meine hat keine Session_StartMethode und sperrt immer noch
Denis G. Labrecque
0

Nachdem ich mit allen verfügbaren Optionen zu kämpfen hatte, schrieb ich schließlich einen JWT-Token-basierten SessionStore-Anbieter (die Sitzung wird in einem Cookie gespeichert und es wird kein Backend-Speicher benötigt).

http://www.drupalonwindows.com/de/content/token-sessionstate

Vorteile:

  • Drop-In-Ersatz, es sind keine Änderungen an Ihrem Code erforderlich
  • Skalieren Sie besser als jeder andere zentralisierte Speicher, da kein Sitzungsspeicher-Backend erforderlich ist.
  • Schneller als jeder andere Sitzungsspeicher, da keine Daten aus einem Sitzungsspeicher abgerufen werden müssen
  • Verbraucht keine Serverressourcen für den Sitzungsspeicher.
  • Standardmäßige nicht blockierende Implementierung: Die gleichzeitige Anforderung blockiert sich nicht gegenseitig und sperrt die Sitzung
  • Skalieren Sie Ihre Anwendung horizontal: Da die Sitzungsdaten mit der Anforderung selbst übertragen werden, können Sie mehrere Webköpfe verwenden, ohne sich um die Sitzungsfreigabe kümmern zu müssen.
David
quelle