none
WEbseite nicht mehr benutzbar, wenn w3wp.exe ca. 2GB Speicher erreicht RRS feed

  • Frage

  • Wir haben einen Webshop (ASP.NET, C#) auf einem Windows Server 2003 SP mit 16GB Hauptspeicher zu laufen.

    Wenn der w3wp.exe*32 ca. 2GB erreicht, ist der Webshop nicht mehr bedienbar. Ich muss dann den Application Pool wiederverwenden.

    Dabei gehen aber Sessions verloren.

    Hat jemand eine Idee?

    Vielen Dank.

    Gregor


    G. Schönhard
    Freitag, 19. November 2010 08:03

Antworten

  • Hallo Gregor,
    Webshopsession ist unsere Klasse, die die Datenbankverbindung und diverse andere Klassen beinhaltet.

    ne, oder? Du willst mir jetzt nicht erzählen, dass ihr SqlConnections, ... in der Session speichert!?!?

    Falls ja, weg damit. Das hat da nichts zu suchen und wird sehr wahrscheinlich mit die Hauptursache für eure Problematiken sein.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Mittwoch, 1. Dezember 2010 19:24
    Moderator

Alle Antworten

  • Hallo Gregor,

    Wir haben einen Webshop (ASP.NET, C#) auf einem Windows Server 2003 SP mit 16GB Hauptspeicher zu laufen.

    Wenn der w3wp.exe*32 ca. 2GB erreicht, ist der Webshop nicht mehr bedienbar. Ich muss dann den Application Pool wiederverwenden.

    warum läuft der IIS als 32 Bit Prozess? Gibt es dafür einen zwingenden Grund?

    Generell würde ich erst mal empfehlen, mehrere Application Pools zu erstellen und für die Website, in der der Shop läuft, einen eigenen anzugeben, der nur für diese Webanwendung gilt.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Freitag, 19. November 2010 08:16
    Moderator
  • Der Webshop läuft in seinem eigenen Application Pool, ansonsten läuft keine Web Anwendung auf diesem Rechner.

    Der Webshop läuft als 32bit, da der Webshop Objekte benutzt, die auch von anderer Software benutzt werden, die als 32 Bit Applikation laufen müssen.

    Ich könnte das natürlich rauslösen, aber eigentlich sollte doch auch eine 32bit Anwendung bei 2GB Hauptspeicher nicht stehenbleiben, oder?
    Danke trotzdem schon mal.


    G. Schönhard
    Freitag, 19. November 2010 12:50
  • Hallo Gregor,

    Ich könnte das natürlich rauslösen, aber eigentlich sollte doch auch eine 32bit Anwendung bei 2GB Hauptspeicher nicht stehenbleiben, oder?

    doch. Die maximale Speichernutzung eines 32 Bit Prozesses liegt nunmal bei 2 GB.

    Siehe dazu auch: http://msdn.microsoft.com/de-de/library/aa366778.aspx

    Ich würde schauen, dass ihr die 32 Bit Objekte eliminiert (wenn machbar).

    Ansonsten würde wohl nur bleiben, die Speichernutzung runterzufahren. Ist der Shop dermaßen gut besucht, dass ihr so viel Speicher verbraucht? Da müssen ja massig Sessions, ... drin sein. Falls ihr große Datenmengen in der Session speichert, solltet ihr das ändern, das ist so oder so nicht gut.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Freitag, 19. November 2010 13:02
    Moderator
  • vielen Dank für die Info, dann schaue ich erst mal, dass ich unseren Webshop fit für 64bit mache lasse.

    Auf dem Webshop ist viel los, wir haben viele hundert Aufträge, der Webshop dient gleichzeitig als Wiederverkäufer Portal.

    Wo speichert man denn die Daten, wenn nicht in der Session? Da müssen ja die Artikeldaten etc. gehalten werden.

    Ich bin kein Entwickler, deshalb ist die Frage evtl. etwas naiv....


    G. Schönhard
    Freitag, 19. November 2010 14:12
  • Hi,
    Auf dem Webshop ist viel los, wir haben viele hundert Aufträge, der Webshop dient gleichzeitig als Wiederverkäufer Portal.

    Wo speichert man denn die Daten, wenn nicht in der Session? Da müssen ja die Artikeldaten etc. gehalten werden.

    die Artikeldaten kommen in die Datenbank :)

    Lediglich bestimmte Informationen wie bspw. ob ein User angemeldet ist und wenn ja, dessen Daten, ggfs. notwendige Daten für einen Rücksprung in der Anwendung zu einer anderen Seite, ... werden in der Session gespeichert.

    Daten, die nicht benutzer- bzw. sessionabhängig sind aber dennoch gecacht werden sollen, kommen eben in den Cache, der anwendungsweit gilt und damit für die gesamte Anwendung nur ein einziges mal Speicherplatz verbraucht, ...

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Freitag, 19. November 2010 15:59
    Moderator
  • Hallo Stefan,

    danke für Deine Hilfe ich werde am Sonntag die 64bit Version einspielen.

    Was mir noch aufgefallen ist, wir benutzen noch .NET 2.0. Bringt mir .Net 3.5 hinsichtlich Performance/Laufzeitverhalten Vorteile?

    Danke.

    Gregor


    G. Schönhard
    Samstag, 20. November 2010 05:58
  • Hallo Gregor,

    danke für Deine Hilfe ich werde am Sonntag die 64bit Version einspielen.

    Was mir noch aufgefallen ist, wir benutzen noch .NET 2.0. Bringt mir .Net 3.5 hinsichtlich Performance/Laufzeitverhalten Vorteile?

    ähm, Du hast AFAICS bereits die 64 Bit Version von Windows installiert. Sonst würde der W3P Prozess nicht als *32 erscheinen.

    Der IIS selbst wird nicht als 32 Bit installiert, sondern das wird über eine Konfigurationseinstellung gesteuert.

    Siehe dazu:

      http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/405f5bb5-87a3-43d2-8138-54b75db73aa1.mspx?mfr=true

    In deinem Fall muss der letzte Parameter nicht "true", sondern "false" lauten. Danach sinnvollerweise den Server komplett neu starten. Es wäre zwar eigentlich nicht notwendig, ist aber IMHO besser.

    3.5 ist eigentlich nur ein Aufsatz auf 2.0. Von daher dürfte das performancetechnisch nicht mehr bringen. Aber aufgrund der doch erheblichen Erweiterungen wäre es ggfs. schon sinnvoll, auf 3.5 zu gehen. Aber das bringt nur dann etwas, wenn ihr diese Features auch verwendet.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Samstag, 20. November 2010 20:21
    Moderator
  • Hallo Stefan,

    unser Webshop läuft jetzt als 64 bit.

    Allerdings blieb nach ca. 4GB die Webseite wieder stehen.

    Es steht nichts im Ereignis Protokoll, unsere Anwendung hat auch keinen Fehler gelogt, im Protokoll des IIS stehen die normalen POST/GET Messages.

    Erst als ich im Application Pool auf Wiederverwendung gegangen bin, lief die Seite wieder...

    Auf der Seite der Wiederverwendung im Application Pool habe ich eingetragen : "Arbeitsprozesse wieder verwenden" nach 60min.

    Hast Du eine Idee???

    Danke.

    Gregor

    P.s. Montag fängt ein Entwickler mit dem Ants Profiler an zu suchen, ob wir ein Speicherleck haben...


    G. Schönhard
    Sonntag, 21. November 2010 08:41
  • Hallo Gregor,

    Allerdings blieb nach ca. 4GB die Webseite wieder stehen.

    warum auch immer die Anwendung sich so mit Speicher vollsaugt. Wenn ihr da nicht massivst Daten cacht und/oder in der Session ablegt, wüsste ich nicht, warum ein einfacher Shop auf 4 GB RAM Verbrauch kommen sollte.

    Es steht nichts im Ereignis Protokoll, unsere Anwendung hat auch keinen Fehler gelogt, im Protokoll des IIS stehen die normalen POST/GET Messages.

    Schaut doch mal mit dem Performance Monitor oder ähnlichem die Anzahl der Sessions, Requests, ... an.

    Erst als ich im Application Pool auf Wiederverwendung gegangen bin, lief die Seite wieder...

    Auf der Seite der Wiederverwendung im Application Pool habe ich eingetragen : "Arbeitsprozesse wieder verwenden" nach 60min.

    Kann es evtl. sein, der ApplicationPool beendet war? Das passiert bspw. wenn man den "Schutz vor schnellen Fehlern" aktiviert hat.

    P.s. Montag fängt ein Entwickler mit dem Ants Profiler an zu suchen, ob wir ein Speicherleck haben...

    Das wäre sicherlich ratsam, denn ich denke schon, dass es damit was zu tun hat. Normal ist das nämlich IMHO nicht.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Sonntag, 21. November 2010 19:58
    Moderator
  • Hallo Stefan,

    ich habe mir heute mal mit dem Perfmon die Anzahl der aktiven ASP.Net angeschaut.

    Bei ziemlich genau 300 Sitzungen war unser Shop plötzlich nicht mehr erreichbar und die Anzahl sank schlagartig auf 0.

    Der Application Pool war nicht beendet, im Browser stand auch nicht Service unavailable, sondern nur "Laden der Seite"

    Was mich ein wenig gewundert hat, dass die Anzahl der aktiven Sitzungen nur nach oben ging.

    Sagt Dir das Verhalten etwas?

    Mit dem Ants Profiler bin ich noch nicht richtig weiter gekommen, die Differenz zwischen bei Memory Snap Shops war 64K, allerdings zeigte der Task Manager einen Anstieg um 2MB an.

    Danke schon mal für Deine Ratschläge.

    Gregor


    G. Schönhard
    Montag, 22. November 2010 19:12
  • Gallo Gregor,

    ich habe mir heute mal mit dem Perfmon die Anzahl der aktiven ASP.Net angeschaut.

    Bei ziemlich genau 300 Sitzungen war unser Shop plötzlich nicht mehr erreichbar und die Anzahl sank schlagartig auf 0.

    dann wurde der Application Pool oder die Anwendung selbst wahrscheinlich doch beendet.

    Ihr könntet testweise mal in den relevanten Events der global.asax Logs mitschreiben (am besten in eine Textdatei mit fest angegebenem Pfad, da bspw. Server.MapPath in einigen Events nicht zur Verfügung steht). Bitte mit Zeitstempel schreiben.

    • Application_Start
    • Application_End
    • Application_Error (inkl. Server.GetLastError()... und der Exception selbst)
    • Session_Start
    • Session_End

    Das Verhalten könnte auch mit irgendeinem Limit zu tun haben. Dazu müsste man sich das Ganze aber mal live anschauen. Schaut auch derweil mal die erweiterten Einstellungen Application Pools an. Da kann man auch einiges zu Limit eintragen.

    Der Application Pool war nicht beendet, im Browser stand auch nicht Service unavailable, sondern nur "Laden der Seite"

    Was mich ein wenig gewundert hat, dass die Anzahl der aktiven Sitzungen nur nach oben ging.

    Sagt Dir das Verhalten etwas?

    Sitzungen werden erst nach ihrem Timeout beendet. Standard sind 20 Minuten, das lässt sich aber per IIS, web.config oder auch per Code ändern.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Montag, 22. November 2010 20:07
    Moderator
  • Hallo Stefan,

    ich habe das eingebaut und eben freigeschaltet.

    Wir hatten in 30 Minuten 1968 Session_starts, dann blieb der Webshop wieder hängen, ohne dass es eine Fehlermeldung gegeben hat.

    Wir hatten 52 Session_ends.

    Hast Du noch eine Idee?

    Danke.

    Gregor

    P.S. wir bauen den Shop grade um, dass einiges in den globalen Cache kommt...

     


    G. Schönhard
    Mittwoch, 24. November 2010 08:52
  • Hallo Gregor,

    Wir hatten in 30 Minuten 1968 Session_starts, dann blieb der Webshop wieder hängen, ohne dass es eine Fehlermeldung gegeben hat.

    Wir hatten 52 Session_ends.

    Wie lange ist denn euer Session Timeout? Wieviel RAM verbraucht eine Session so im Durchschnitt?

    Ggfs. haut es doch einfach den Application Pool wegen einer zu hohen RAM Auslastung des Prozesses durcheinander. Wie sehen denn die Einstellung des Application Pools aus?

    BTW: Die Einstellung, dass der Application Pool nach 60 Minuten wiederverwendet werden soll, ist suboptimal.

    Recyclet den AppPool lieber kontrolliert nachts.

    Ansonsten fällt mir wirklich nur die Anwendung selbst als Übeltäter ein.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Mittwoch, 24. November 2010 23:19
    Moderator
  • Hallo Stefan,

    unser session timeout liegt bei 30min. Eine Session hat 4MB Speicher.

    Der Application Pool hat folgende Einstellungen :

    max. verwendeter Speicher  : 4GB

    Arbeitsprozesse im Leerlauf runterfahren nach : 20min

    Warteschlange für Kernelanforderung : 1000

    Webgarten : 1

    Pingen aktiviert

    Schutz für schnelle Fehler : deaktiv

    Gruß

    Gregor


    G. Schönhard
    Donnerstag, 25. November 2010 08:33
  • Hallo Gregor,

    unser session timeout liegt bei 30min. Eine Session hat 4MB Speicher.

    Öhm. 4 MB pro Session? Ein wenig viel, findest Du nicht?

    max. verwendeter Speicher  : 4GB

    Dann lass mich mal rechnen: 4 MB * 1968 Sessions = ca. 7,6 GB. Ein wenig viel zu viel. Und dann wird der AppPool wohl auch nicht mehr wollen, da sein konfiguriertes Limit erreicht wurde und er dann wartet, bis wieder was frei ist. Deaktiviert die Max. Speicher Einstellung bitte.

    Aber ihr solltet dringend was an der Anwendung ändern. Eine Session sollte nicht 4 MB verbraten. Es gibt ganz, ganz wenige Ausnahmefälle, in denen man sowas benötigt. Ein Shop gehört definitiv nicht dazu.

    Arbeitsprozesse im Leerlauf runterfahren nach : 20min

    Solltet ihr mind. auf die Zeit des Sessiontimeouts ändern.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 25. November 2010 08:49
    Moderator
  • ja, ich weiss, dass das viel zu viel ist, ich war auch erstaunt, das wird grade umgebaut, wir benutzen viel zu viele Objekte...

    Ich habe herausgefunden, dass der Webshop nicht mehr benutzbar wird, wenn zum ersten Mal das Session Timout greift.

    D.h. session Timeout = 30, nach 30 Minuten geht im Webshop nix mehr.

    Ich habe auf den Perfmon raufgeschaut: Bis zur 30. Minute stiegt die Anzahl der ASP.NET Anwendungen nur.

    Bei Minute 30 ging die Anzahl der ASP.NET Anwendungen runter, blieb dann für kurze Zeit konstant, viel dann auf 0, um kurze Zeit wieder auf den Maximalwert zu steigen. Der Webshop blieb aber weiterhin nicht benutzbar.

    Sagt Dir dieses Verhalten was?

    Danke.

    Gregor


    G. Schönhard
    Donnerstag, 25. November 2010 11:26
  • Hallo Gregor,

    Bei Minute 30 ging die Anzahl der ASP.NET Anwendungen runter, blieb dann für kurze Zeit konstant, viel dann auf 0, um kurze Zeit wieder auf den Maximalwert zu steigen. Der Webshop blieb aber weiterhin nicht benutzbar.

    und die Prozessor- und Speicherauslastung des Servers selbst war völlig im normalen Rahmen?

    Eigentlich sieht mir das nach einem Fehler bei Session_End aus. Macht ihr da irgendwas in der Methode? Kann es sein, dass dort Fehler auftreten oder ggfs. Operationen gestartet werden, die irgendetwas lahmlegen?

    Falls ihr in Session_End Code drin habt, poste den (und ggfs. weitere genutzte Methoden) bitte mal hier.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Samstag, 27. November 2010 16:50
    Moderator
  • Hallo Stefan,

    die Prozessor und Speicherauslastung ist im normalen Bereich.

    im session_end steht folgendes :

    protected void Session_End(Object sender, EventArgs e)
            {
                WebshopSession webshopSession = Session[WebshopSession.WEBSHOP_SESSION] as WebshopSession;

                // Direkter aufruf, da im Logger der Session-Context bereits weg ist
                WriteSessionLog(this, new LogEventArgs("SESSION_END"), webshopSession);
                webshopSession.Close();
                Session[WebshopSession.WEBSHOP_SESSION] = null;

                if (ExistsDebugLog())
                    File.AppendAllText(debugLogPath, string.Format("{0}Session_End -------------- Datum: {1}", Environment.NewLine, DateTime.Now));
            }

    public override void Close()
            {
                try
                {
                    Logout();
                    base.Close(); // die Session der Datenbank Objekte
                }
                catch (Exception e)
                {
                    HandleException(e);
                }
            }

    public void Logout()
            {
                try
                {
                    myCustomerRecord = null;
                    myActiveSale = null;
                    myCustomerIsReseller = false;
                    myCountry = Country.Germany;

                    myManufacturerRecord = null;

                    //HttpContext.Current.Session.Abandon();
                }
                catch (Exception e)
                {
                    HandleException(e);
                }
            }

    Webshopsession ist unsere Klasse, die die Datenbankverbindung und diverse andere Klassen beinhaltet.

    Danke.

    Gregor


    G. Schönhard
    Montag, 29. November 2010 10:35
  • Hallo Gregor,
    Webshopsession ist unsere Klasse, die die Datenbankverbindung und diverse andere Klassen beinhaltet.

    ne, oder? Du willst mir jetzt nicht erzählen, dass ihr SqlConnections, ... in der Session speichert!?!?

    Falls ja, weg damit. Das hat da nichts zu suchen und wird sehr wahrscheinlich mit die Hauptursache für eure Problematiken sein.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Mittwoch, 1. Dezember 2010 19:24
    Moderator
  • Hallo Stefan,

    was ist denn die beste Methode, die SQlConnectons zu speichern?

    Gruß

    Gregor


    G. Schönhard
    Donnerstag, 2. Dezember 2010 09:05
  • Hallo Gregor,

    was ist denn die beste Methode, die SQlConnectons zu speichern?

    warum in aller Welt soll man SQL Connections speichern? Eine Webanwendung ist etwas _komplett_ anderes als eine Offlineanwendung. Es gibt Request -> Response und damit hat sich das erstmal. Es gibt keine dauerhafte Verbindung zwischen Client und Server. Jeder Request ist etwas _komplett_ neues und jedes benötigte Objekt wird dabei dann auch _komplett_ neu erstellt.

    In deinem Fall ist das bspw. so: Es werden 1.500 Sessions generiert und damit dann auch 1.500 Verbindungen zur Datenbank aufgebaut. Im Worst Case wird jede Session erstellt und liegt dann einfach brach (bspw. dann, wenn der Client keine Sessioncookies akzeptiert und man nicht mit Url Parametern für die Session Id arbeitet).

    Was man machen kann, ist, die Connection und anderes, was man für den gesamten Request an vielen Stellen benötigt, in HttpContext.Current.Items unterzubringen und bspw. über eine statische Methode dort wieder auszulesen. Wenn mans falsch macht, ist das aber ziemlich gefährlich, daher muss man drauf achten, dass man wirklich die richtigen Objekte wieder ausliest :)

    Dass das ggfs. eine Umstellung eines Großteils eurer Anwendungslogik mit sich bringt ist mir klar. Aber da werdet ihr nicht drum rum kommen. So kann es IMHO auf jeden Fall nicht bleiben.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 2. Dezember 2010 09:23
    Moderator
  • Hallo Stefan,

    das hatte ich mir schon fast gedacht...

    Dann werde ich mal ein Konzept zur Umstellung machen.

    Vielen Dank auf jeden Fall nochmal für Deine umfangreiche Hilfe.

    Gibt es evtl. ein gutes Buch "best practice" zum Schreiben von Webanwendungen?

    Gruß

    Gregor


    G. Schönhard
    Donnerstag, 2. Dezember 2010 10:47