La causa più frequente di perdita delle sessioni è il crash del processo w3wp o il restart dell’AppDomain che processa l’applicazione.
Quando si nota che l’applicazione perde le sessioni la prima cosa da fare è abilitare i WebEvent: ASP.NET Health Monitoring http://msdn.microsoft.com/en-us/library/ms178701(VS.80).aspx
Si apra il Web.Config e, all’interno del tag <System.Web> si aggiunga quanto segue:
<healthMonitoring enabled="true" heartbeatInterval="0"> <rules> <add name="Lifetime event logging rule" eventName="Application Lifetime Events" provider="EventLogProvider" /> </rules> </healthMonitoring>
A questo punto, in caso di restart dell’Applicazione, tipicamente vengono registrati i seguenti messaggi nell’EventLog:
Event Type: InformationEvent Source: ASP.NET 2.0.50727.0Event Category: Web Event Event ID: 1305Date: Time: 3:00:11 PMUser: Computer: Description:Event code: 1001 Event message: Application is starting. Event time: Event time (UTC): Event ID: e842cd86c62940788ed106f0f58ae8e4 Event sequence: 1 Event occurrence: 1 Event detail code: 0 Application information: Application domain: Trust level: Full Application Virtual Path: Application Path: Machine name: Process information: Process ID: 1600 Process name: w3wp.exe Account name: Event Type: InformationEvent Source: ASP.NET 2.0.50727.0Event Category: Web Event Event ID: 1305Date: Time: 3:00:11 PMUser: Computer: Description:Event code: 1002 Event message: Application is shutting down.Event time: Event time Event ID: b1294ac7629241b8b385cc1312b31dae Event sequence: 2361 Event occurrence: 1 Event detail code: 50001
Event Type: InformationEvent Source: ASP.NET 2.0.50727.0Event Category: Web Event Event ID: 1305Date: Time: 3:00:11 PMUser: Computer: Description:Event code: 1001 Event message: Application is starting. Event time: Event time (UTC): Event ID: e842cd86c62940788ed106f0f58ae8e4 Event sequence: 1 Event occurrence: 1 Event detail code: 0 Application information: Application domain: Trust level: Full Application Virtual Path: Application Path: Machine name: Process information: Process ID: 1600 Process name: w3wp.exe Account name:
Event Type: InformationEvent Source: ASP.NET 2.0.50727.0Event Category: Web Event Event ID: 1305Date: Time: 3:00:11 PMUser: Computer: Description:Event code: 1002 Event message: Application is shutting down.Event time: Event time Event ID: b1294ac7629241b8b385cc1312b31dae Event sequence: 2361 Event occurrence: 1 Event detail code: 50001
Per saperne di più è possibile prendere dei dump in crash mode.
Ecco come procedere all’analisi.
1) Carico l’estensione sos
2) Trovo tutte le istanze di HttpRuntime presenti nella heap
0:000> .loadby sos.dll mscorwks0:000> !dumpheap -type System.Web.HttpRuntime------------------------------Heap 3 Address MT Size07892270 6639a67c 152 0789d268 6639a67c 152 total 2 objects
3) Dumpo l’istanza per vederne i campi:
0:000> !do 0789d268 Name: System.Web.HttpRuntimeMethodTable: 6639a67cEEClass: 6639a60cSize: 152(0x98) bytes (C:\WINDOWS\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll)Fields: MT Field Offset Type VT Attr Value Name791132b4 40010f8 4 ...amedPermissionSet 0 instance 00000000 _namedPermissionSet6639b12c 40010f9 8 ...ileChangesMonitor 0 instance 0789d75c _fcm6639e2c8 40010fa c ...ing.CacheInternal 0 instance 0789f540 _cacheInternal6639d878 40010fb 10 ...Web.Caching.Cache 0 instance 0789f458 _cachePublic7910be50 40010fc 74 System.Boolean 1 instance 0 _isOnUNCShare6639ad78 40010fd 14 ...Web.Util.Profiler 0 instance 0789d300 _profiler6639ae78 40010fe 18 ...estTimeoutManager 0 instance 0789d31c _timeoutManager663aebe4 40010ff 1c ....Web.RequestQueue 0 instance 078fe1a4 _requestQueue7910be50 4001100 75 System.Boolean 1 instance 0 _apartmentThreading7910be50 4001101 76 System.Boolean 1 instance 1 _processRequestInApplicationTrust7910be50 4001102 77 System.Boolean 1 instance 0 _beforeFirstRequest7910c878 4001103 84 System.DateTime 1 instance 0789d2ec _firstRequestStartTime7910be50 4001104 78 System.Boolean 1 instance 1 _firstRequestCompleted7910be50 4001105 79 System.Boolean 1 instance 1 _userForcedShutdown7910be50 4001106 7a System.Boolean 1 instance 1 _configInited7910be50 4001107 7b System.Boolean 1 instance 1 _fusionInited79102290 4001108 6c System.Int32 1 instance 0 _activeRequestCount7910c878 4001109 8c System.DateTime 1 instance 0789d2f4 _lastShutdownAttemptTime7910be50 400110a 7c System.Boolean 1 instance 1 _shutdownInProgress790fd8c4 400110b 20 System.String 0 instance 100171a4 _shutDownStack790fd8c4 400110c 24 System.String 0 instance 07f25c80 _shutDownMessage663e8730 400110d 70 System.Int32 1 instance 1 _shutdownReason790fd8c4 400110e 28 System.String 0 instance 078c4f00 _trustLevel790fd8c4 400110f 2c System.String 0 instance 0789d508 _wpUserId7910be50 4001110 7d System.Boolean 1 instance 1 _shutdownWebEventRaised7910be50 4001111 7e System.Boolean 1 instance 1 _enableHeaderChecking7910d7e8 4001112 30 System.AsyncCallback 0 instance 0789d53c _requestNotificationCompletionCallback7910d7e8 4001113 34 System.AsyncCallback 0 instance 0789d55c _handlerCompletionCallback6639b038 4001114 38 ...fSendNotification 0 instance 0789d57c _asyncEndOfSendCallback791186fc 4001115 3c ...ding.WaitCallback 0 instance 0789d59c _appDomainUnloadallback790fdf04 4001116 40 System.Exception 0 instance 00000000 _initializationError7910be50 4001117 7f System.Boolean 1 instance 0 _hostingInitFailed791127fc 4001118 44 ...m.Threading.Timer 0 instance 00000000 _appDomainShutdownTimer790fd8c4 4001119 48 System.String 0 instance 078d5cd0 _tempDir790fd8c4 400111a 4c System.String 0 instance 078d5ee8 _codegenDir790fd8c4 400111b 50 System.String 0 instance 07891820 _appDomainAppId790fd8c4 400111c 54 System.String 0 instance 07891864 _appDomainAppPath6639b220 400111d 58 ...m.Web.VirtualPath 0 instance 0789d734 _appDomainAppVPath790fd8c4 400111e 5c System.String 0 instance 0789321c _appDomainId7910be50 400111f 80 System.Boolean 1 instance 0 _debuggingEnabled7912dae8 4001120 60 System.Byte[] 0 instance 00000000 _appOfflineMessage790fd8c4 4001121 64 System.String 0 instance 00000000 _clientScriptVirtualPath790fd8c4 4001122 68 System.String 0 instance 00000000 _clientScriptPhysicalPath
Si può subito vedere che il campo _shutdownInProgress è valorizzato a 1, il che significa che l’AppDomain sta per essere scaricato dalla memoria.
4) Possiamo dumpare lo _shudownStack e lo _shutdownMessage per avere maggiori dettagli:
0:000> !do 100171a4 Name: System.StringMethodTable: 790fd8c4EEClass: 790fd824Size: 1038(0x40e) bytesGC Generation: 1 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)String: at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace() at System.Web.Hosting.HostingEnvironment.InitiateShutdownInternal() at System.Web.Hosting.HostingEnvironment.UnregisterRunningObjectInternal(IRegisteredObject obj) at System.Web.Hosting.HostingEnvironment.UnregisterObject(IRegisteredObject obj) at System.Web.Hosting.ISAPIRuntime.StopProcessing()0:000> !do 07f25c80 Name: System.StringMethodTable: 790fd8c4EEClass: 790fd824Size: 164(0xa4) bytesGC Generation: 1 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)String: Overwhelming Change NotificationHostingEnvironment caused shutdown
Risulta ora chiaro il motivo per cui l’applicazione viene riavviata. Qualcuno o qualcosa sta scrivendo, modificando o cancellando i file dell’applicazione o il virtual path all’interno del quale l’applicazione è contenuta
Ecco infatti alcune delle possibili cause di AppDomain restart:
Application Restarts Modifying the source code of your Web application will cause ASP.NET to recompile source files into assemblies. When you modify the top-level items in your application, all other assemblies in the application that reference the top-level assemblies are recompiled as well. In addition, modifying, adding, or deleting certain types of files within the application's known folders will cause the application to restart. The following actions will cause an application restart: Adding, modifying, or deleting assemblies from the application's Bin folder. Adding, modifying, or deleting localization resources from the App_GlobalResources or App_LocalResources folders. Adding, modifying, or deleting the application's Global.asax file. Adding, modifying, or deleting source code files in the App_Code directory. Adding, modifying, or deleting Profile configuration. Adding, modifying, or deleting Web service references in the App_WebReferences directory. Adding, modifying, or deleting the application's Web.config file. When an application restart is required, ASP.NET will serve all pending requests from the existing application domain and the old assemblies before restarting the application domain and loading the new assemblies.
Modifying the source code of your Web application will cause ASP.NET to recompile source files into assemblies. When you modify the top-level items in your application, all other assemblies in the application that reference the top-level assemblies are recompiled as well.
In addition, modifying, adding, or deleting certain types of files within the application's known folders will cause the application to restart. The following actions will cause an application restart:
Adding, modifying, or deleting assemblies from the application's Bin folder.
Adding, modifying, or deleting localization resources from the App_GlobalResources or App_LocalResources folders.
Adding, modifying, or deleting the application's Global.asax file.
Adding, modifying, or deleting source code files in the App_Code directory.
Adding, modifying, or deleting Profile configuration.
Adding, modifying, or deleting Web service references in the App_WebReferences directory.
Adding, modifying, or deleting the application's Web.config file.
When an application restart is required, ASP.NET will serve all pending requests from the existing application domain and the old assemblies before restarting the application domain and loading the new assemblies.
Estratto da ASP.NET Application Life Cycle Overview for IIS 5.0 and 6.0
A partire dal Framework 2.0 se n’è inoltre aggiunto un altro:
Application Sub-Directories are deleted
Quest’ultimo punto è discusso in dettaglio nel seguente post: Todd Carter's WebLog : Deleting ASP.NET 2.0 Application Sub-Directories Shuts Down the AppDomain
Per monitorare il Virtual Path e vedere se qualcuno vi scrive dentro o ne modifica l’albero una possibilità è quella di usare il Process Monitor.
Una volta individuata la causa e scoperto chi e cosa compie le operazioni incriminate, è possibile agire in due modi:
- il primo, consigliato, è quello di rimuovere la causa facendo si che il Virtual Path non venga toccato
- il secondo, molto più delicato e da valutare con attenzione, è quello di disabilitare parzialmente o totalmente la File Change Notification come spiega questo articolo (che però discute un altro problema: FIX: ASP.NET 2.0-connected applications on a Web site may appear to stop responding
Nella fattispecie di questo caso, era l’applicazione stessa a creare e cancellare cartelle e file al di sotto della root applicativa. Si è optato per la seconda soluzione perché, per motivi di policy interne, non era possibile spostare il working path al di fuori della root.
Alla prossima
Stefano Pronti Senior Support Engineer EMEA IIS and Web Developer Support Team