ASPNET ApplicationStart事件觸發(fā)時(shí)間_第1頁
ASPNET ApplicationStart事件觸發(fā)時(shí)間_第2頁
ASPNET ApplicationStart事件觸發(fā)時(shí)間_第3頁
ASPNET ApplicationStart事件觸發(fā)時(shí)間_第4頁
ASPNET ApplicationStart事件觸發(fā)時(shí)間_第5頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

ASP.NET Case Study: Lost session variables and appdomain recyclesRATE THISLast night I got a question from one of the readers of the blog that went like this:“We are facing a problem that i cannot understand, every now and than i see that my app domain is recycled (i have a log in the application_end), I check the IIS logs and i dont see a restart of IIS and i know that no one is changing configuration (web.config).I wanted to know if you know of any way that i can pinpoint the reason for that app domain to die?The application pool that i am using only have the recycle every 20 minutes of idle time enabled“.and I thought that since I havent written for a while (due to a really nice and long vacationJ) and this is a pretty common scenario I would write a post on itBefore we go into the details of how to figure out why it is recycling I want to bring up two things1. What happens when an application domain is recycled2. What are the reasons an application domain recyclesWhat happens when an application domain is recycled?In ASP.NET each individual application resides in its own application domain, so for example if you have the following website structureWebSite root/HrWeb/EmployeeServices/FinanceWeb/SalesWebwhere each of the subwebs HrWeb, EmployeeServices etc. are set up as anapplication in the internet service manager, you will have the following application domains (appdomains) in your processSystem DomainShared DomainDefault DomainRootHrWebEmployeeServicesFinanceWebSalesWebApart from the first three domains (in italic) which are a bit special, each of the other ones contain the data pertinent to that application (Note: this is a bit simplified for readability), specifically they contain these things worth noting1. All the assemblies specific to that particular application2. A HttpRuntime object3. A Cache objectWhen the application domain is unloaded all of this goes away, which means that on the next request that comes in all assemblies need to be reloaded, the code has to be re-jitted and the cache including any in-proc session variables etc. are empty.This can be a pretty big perf-hit for the application so as you can imagine it is important to not have the application domain recycle too often.Why does an application domain recycle?An application domain will unload when any one of the following occurs: Machine.Config, Web.Config or Global.asax are modified The bin directory or its contents is modified The number of re-compilations (aspx, ascx or asax) exceeds the limit specified by the setting in machine.config or web.config(by default this is set to 15) The physical path of the virtual directory is modified The CAS policy is modified The web service is restarted (2.0 only) Application Sub-Directories are deleted (see Todds blog/toddca/archive/2006/07/17/668412.aspxfor more info)There may be some reasons in 2.0 that I have missed but hopefully this should cover most scenarios.Specific issuesI want to pay a bit more attention to a few of these, which seem to be especially popularJUnexpected config or bin directory changesYou swear on all that is holy that no-one is touching these, but still when we start logging (as Ill show later) the reason for the app domain recycle is a config change how the heck can that be?Elementary, Dr. Watson something else is touching them and that something else is usually a virus scanning software or backup software or an indexing service.They dont actually modify the contents of the files, but many virus scanners etc. will modify attributes of files which is enough for the file changes monitor to jump in and say “aha !, something changed, better recycle the appdomain to update the changes”.If you have a virus scanner that does this, you should probably consider removing the content directories from the real-time scan, of course after carefully making sure that no-one can access and add any virus software to these directories.Web site updates while the web server is under moderate to heavy loadPicture this scenario:You have an application with 10 assemblies in the bin directorya.dll, b.dll, c.dll etc. (all with the version number 1.00.00). Now you need to update some of the assemblies to your new and improved version 1.00.12, and you do so while the application is still under heavy load because we have this great feature allowing you to update assemblies on the go well, think again.Say you update 7 of the 10 assemblies and for simplicity lets say this takes about 7 seconds, and in those 7 seconds you have 3 requests come in then you may have a situation that looks something like thisSec 1.a.dll and b.dll are update to v 1.00.12- appdomain unload started (any pending requests will finish before it is completely unloaded)Sec 2.Request1 comes in and loads a new appdomain with 2 out of 7 of the dlls updatedSec 3.c.dll is updated- appdomain unload started(any pending requests will finish before it is completely unloaded)Sec 4.d.dll is updatedSec 5.Request2 comes in and loads a new appdomain, now with 4 out of 7 dlls updatedSec 6.e.dll and f.dll is updated- appdomain unload started(any pending requests will finish before it is completely unloaded)Sec 7.f.dll is updatedSec 8.Request3 comes in and loads a new appdomain with all 7 dlls updatedSo, many bad things happened hereFirst off you had 3 application domain restarts while you probably thought you would only have one, because has no way of knowing when you are done.Secondly we got a situation where Request1 and Request2 were executing with partially updated dlls, which may generate a whole new set of exceptions if the dlls depend on updates in the other new dlls, I think you get the pictureAnd thirdly you may get exceptions like “Cannot access file AssemblyName because it is being used by another process” because the dlls are locked during shadow copying./kb/810281In other words, dont batch update during loadSo, is this feature completely worthless?No if you want to update one dll, none of the problems above occur and if you update under low or no load you are not likely to run into any of the above issues, so in that case you save yourself an IIS restart but if you want to update in bulk you should first take the application offline.There is a way to get around it, if you absolutely, positively need to update under load, and it is outlined in the kb article mentioned aboveIn 1.1 we introduced two new config settings called and .The waitChangeNotification indicates how many seconds we should wait for a new change notification before the next request triggers an appdomain restart. I.e. if we have a dll updated at second 1, and then a new one at second 3, and our waitChangeNotification is set to 5 we would wait until second 8 (first 1+5, and then changed to 3+5) before a new request would get a new domain, so a request at second 2 would simply continue using the old domain. (The time is sliding so it is always 5 seconds from the last change)The maxWaitChangeNotification indicates the maximum number of seconds to wait from the first request. If we set this to 10 in the case where we update at second 1 and 3, we would still get a new domain if a request came in at second 8 since the waitChangeNotification expired. If we set this to 6 however, we would get a new domain already if a request came in at second 7, since the maxWaitChangeNotification had then expired.So this is an absolute expiration rather than a sliding and we will recycle at the earliest of the maxWaitChangeNotification and waitChangeNotification.In the scenario at the beginning of this section we could have set the waitChangeNotification to 3 seconds and the maxWaitChangeNotification to 10 seconds for example to avoid the problems.(I know this explanation might have been a bit confusion but I hope you catch the drift)A few things are important if you fiddle with these settings1. They default to 0 if not set2. maxWaitChangeNotification should always be = waitChangeNotification3. If these settings are higher than 0 you will not see any changes until the changeNotifications expire. i.e. web.config changes and dll changes etc. will appear cached.Re-compilationsA common scenario here is that you have a set of aspx pages (containing some news items and what not) and you have a content editor that goes in periodically and updates the news with some new articles or other new content.Every time you update an aspx page it has to be recompiled, because again, has no way of knowing if it was a code update or just update of some static text all it knows is that someone updated the files.If you have followed some of my previous posts you know that assemblies can not be unloaded unless the application domain is unloaded, and since each recompile would generate a new assembly there is a limit to how many recompiles you can do, to avoid generation of too many assemblies (and thus limiting the memory usage for these).By default this limit is 15.If the contents of the page is constantly updated I would recommend to dynamically get the content from a database or file rather than actually modifying the aspx pages. Or alternatively using frames with HTML pages for this content.How do you determine that you have application recycles?If you experience cache or session loss, it is probably a good bet, but to make sure you can look at the perfmon counter ASP.NET v/Application Restarts.How do you determine what caused an appdomain restart?In ASP.NET 2.0 you can use the built in Health Monitoring Events to log application restarts along with the reason for the restart.To do this you change the master web.config file in the C:WINDOWSMicrosoft.NETFrameworkv2.0.50727CONFIG directory and add the following to the sectionFor a web.config change this generates an event like so:Event Type:InformationEvent Source:ASP.NET 2.0.50727.0Event Category:Web EventEvent ID:1305Date:2006-08-02Time:13:33:19User:N/AComputer:PRATHERDescription:Event code: 1002Event message: Application is shutting down. Reason: Configuration changed.Event time: 2006-08-02 13:33:19Event time (UTC): 2006-08-02 11:33:19Event ID: 6fc2b84de5b74b5ba65b21804d18b7bfEvent sequence: 8Event occurrence: 1Event detail code: 50004Application information:Application domain: /LM/w3svc/1/ROOT/DebuggerSamples-9-127989919076505325Trust level: FullApplication Virtual Path: /DebuggerSamplesApplication Path: c:inetpubwwwrootDebuggerSamplesMachine name: PRATHERProcess information:Process ID: 4876Process name: w3wp.exeAccount name: NT AUTHORITYNETWORK SERVICECustom event details:For more information, see Help andSupportCenterat /fwlink/events.asp.There is a lot of nice events to capture and you can even write your own providers and events. To get more info about this and other events you can enable, you can check out this article:/en-us/library/ms228103.aspxFor ASP.NET 1.1 you can make use of private reflection to get a hold of the shutdown message (this works in 2.0 as well btw, but I wanted to show you both ways).If you are not interested in the details and just want to cut to the chase and log it, check out ScottGus blog/scottgu/archive/2005/12/14/433194.aspxon how to do this (super nice with ready-to-go code samples that you just plug in to your app).If you are like me and need to know every little detail of every little thing here is how its doneJAs I mentioned before, each domain has a HttpRuntime object0:014 !do 0x04f6f324Name: System.Web.HttpRuntimeMethodTable 0x00e39df4EEClass 0x0b608028Size 116(0x74) bytesGC Generation: 2mdToken: 0x02000078(c:winntassemblygacsystem.web1.0.5000.0_b03f5f7f11d50a3asystem.web.dll)FieldDesc*: 0x00e3955cMTFieldOffsetTypeAttrValue Name0x00e39df4 0x40006800x4CLASSinstance 0x00000000 _namedPermissionSet0x00e39df4 0x40006810x8CLASSinstance 0x01031904 _fcm0x00e39df4 0x40006820xcCLASSinstance 0x01031b64 _cache0x00e39df4 0x40006830x54System.Booleaninstance 0 _isOnUNCShare0x00e39df4 0x40006840x10CLASSinstance 0x01033c88 _profiler0x00e39df4 0x40006850x14CLASSinstance 0x01033ca4 _timeoutManager0x00e39df4 0x40006860x18CLASSinstance 0x0104ded4 _requestQueue0x00e39df4 0x40006870x55System.Booleaninstance 0 _apartmentThreading0x00e39df4 0x40006880x56System.Booleaninstance 0 _beforeFirstRequest0x00e39df4 0x40006890x60VALUETYPEinstance start at 0x010318c8 _firstRequestStartTime0x00e39df4 0x400068a0x57System.Booleaninstance 1 _firstRequestCompleted0x00e39df4 0x400068b0x58System.Booleaninstance 0 _userForcedShutdown0x00e39df4 0x400068c0x59System.Booleaninstance 1 _configInited0x00e39df4 0x400068d0x50System.Int32instance 0 _activeRequestCount0x00e39df4 0x400068e0x5aSystem.Booleaninstance 0 _someBatchCompilationStarted0x00e39df4 0x400068f0x5bSystem.Booleaninstance 0 _shutdownInProgress0x00e39df4 0x40006900x1cCLASSinstance 0x00000000 _shutDownStack0x00e39df4 0x40006910x20CLASSinstance 0x00000000 _shutDownMessage0x00e39df4 0x40006920x68VALUETYPEinstance start at 0x010318d0 _lastShutdownAttemptTime0x00e39df4 0x40006930x5cSystem.Booleaninstance 1 _enableHeaderChecking0x00e39df4 0x40006940x24CLASSinstance 0x01033e44 _handlerCompletionCallback0x00e39df4 0x40006950x28CLASSinstance 0x01033e60 _asyncEndOfSendCallback0x00e39df4 0x40006960x2cCLASSinstance 0x01033e7c _appDomainUnloadallback0x00e39df4 0x40006970x30CLASSinstance 0x00000000 _initializationError0x00e39df4 0x40006980x34CLASSinstance 0x00000000 _appDomainShutdownTimer0x00e39df4 0x40006990x38CLASSinstance 0x0104dc60 _codegenDir0x00e39df4 0x400069a0x3cCLASSinstance 0x00fc3c48 _appDomainAppId0x00e39df4 0x400069b0x40CLASSinstance 0x00fc3ca4 _appDomainAppPath0x00e39df4 0x400069c0x44CLASSinstance 0x00fc3d8c _appDomainAppVPath0x00e39df4 0x400069d0x48CLASSinstance 0x00fc3d04 _appDomainId0x00e39df4 0x400069e0x4cCLASSinstance 0x00000000 _resourceManager0x00e39df4 0x400069f0x5dSystem.Booleaninstance 0 _debuggingEnabled0x00e39df4 0x40006a00x5eSystem.Booleaninstance 0 _vsDebugAttach0x00e39df4 0x400067b0CLASSsharedstatic _theRuntime Domain:Value 0x0014af68:NotInit0x0017cd60:0x04f6f3240x002165d0:0x04fcb660 Domain:Value 0x0014af68:NotInit0x0017cd60:0x04f6ef28 0x002165d0:0x04fcb474 Domain:Value 0x0014af68:NotInit0x0017cd60:1 0x002165d0:1 Domain:Value 0x0014af68:NotInit0x0017cd60:0x04f6f19c 0x002165d0:0x04fcb4d8 Domain:Value 0x0014af68:NotInit0x0017cd60:1 0x002165d0:1 Domain:Value 0x0014af68:NotInit0x0017cd60:0x04f6f3240x002165d0:0x04fcb660This means that in domain 0x0014af68 we havent initialized this object yet,in domain 0x0017cd60 it is located at address 0x04f6f324, and in domain 0x002165d0 it is located at address 0x04fcb660.You can get the address of your domain from !dumpdomain, for example this one is f

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論