I have a web farm hosted in the Azure environment (Windows Server Datacenter 2016 + IIS 10). To configure the IIS on the routing server I need to use the application initialization feature. The IIS on routing server has the ARR, URLRewrite and ExternalDiskCache
extensions installed. To enable application initialization I add the following code to theweb.config file:
<applicationInitialization skipManagedModules="true"><add initializationPage="/" /></applicationInitialization>
When the server is started I set up application pool and web application properties in the WebRole.OnStart method as follows:
using(var serverManager = new ServerManager()) {
foreach(var application in serverManager.Sites.SelectMany(c => c.Applications)) {
application["preloadEnabled"] = true;
}
foreach(var appPool in serverManager.ApplicationPools) {
appPool["startMode"] = "AlwaysRunning";
}
serverManager.CommitChanges();
}Everything is working fine until the application pool is restarted. Once it is stopped it is failed to start again with the following exception in the Windows event log:
Faulting application name: w3wp.exe, version: 10.0.14393.0, time stamp: 0x57899b8a
Faulting module name: iiscore.dll, version: 10.0.14393.1532, time stamp: 0x5965b173
Exception code: 0xc0000005
Fault offset: 0x000000000002adff
Faulting process id: 0x1298
Faulting application start time: 0x01d34424c5dd323c
Faulting application path: d:\windows\system32\inetsrv\w3wp.exe
Faulting module path: D:\Windows\system32\inetsrv\iiscore.dll
Report Id: 690b6f1e-9754-4699-9737-aed6823c0713
Faulting package full name:
Faulting package-relative application ID:
When analyzing dumps with the DebugDiag tool I found the following stack trace:
iiscore!W3_CONTEXT::TagRequestForAppWarmup+37
iiscore!W3_CONTEXT::SetupStateMachinePhase2+125ea
iiscore!W3_CONTEXT::SetupStateMachine+6b4
iiscore!W3_CONTEXT_BASE::StartNotificationLoop+79
iiscore!APPLICATION_PRELOAD_PROVIDER::ExecuteRequest+a5
warmup!DoApplicationPreload+361
iiscore!W3_SERVER::GlobalNotify+c8
iiscore!W3_SERVER::NotifyApplicationPreload+6c
iiscore!IISCORE_PROTOCOL_MANAGER::PreloadApplication+7b
w3wphost!W3WP_HOST::ProcessPreloadApplications+df
w3wphost!WP_IPM::AcceptMessage+220
iisutil!IPM_MESSAGE_PIPE::MessagePipeCompletion+1c1
ntdll!RtlpTpWaitCallback+8d
ntdll!TppExecuteWaitCallback+8c
ntdll!TppWorkerThread+923
kernel32!BaseThreadInitThunk+14
ntdll!RtlUserThreadStart+21
After making some research I noticed that the application pool is successfully restarted if I remove theadd attribute from the applicationInitialization section:
<applicationInitialization skipManagedModules="true"></applicationInitialization>
However, I need to use some initialization logic in my application. Changing the initialization page path also doesn't have any effect. It doesn't matter if I have an .aspx page or a simple text file.
This article describes how to set up the application
initialization with the URL Rewrite module. So I made a series of experiments with the URL Rewrite. By default, it has a single rule defined by the ARR which routes all request to farm:
<rule name="ARR_MyFarm_loadbalance" enabled="true" patternSyntax="Wildcard" stopProcessing="true"><match url="*" /><conditions logicalGrouping="MatchAll" trackAllCaptures="false" /><action type="Rewrite" url="http://MyFarm/{R:0}" /></rule>If I disable this rule, the application pool stops crashing after restart. However, the farm doesn't work
So I
suppose that the reason for application crash is the incorrect configuration of the URL Rewrite module which tries to route the initialization page request to the farm.
I tried to write some additional rules to execute before this rule on initialization stage but without success - it seems that if the "farm" rule is enabled, it always performs routing. I used the patterns with APP_WARMING_UP server variable but it doesn't
seem to help. I have the following rule set:
<rewrite><globalRules><clear /><rule name="Home page short" enabled="true" stopProcessing="true"><match url="^$" /><conditions logicalGrouping="MatchAll" trackAllCaptures="false"><add input="{APP_WARMING_UP}" pattern="1" /></conditions><action type="Rewrite" url="Startup.htm" /></rule><rule name="AllRequests" enabled="true" stopProcessing="true"><match url=".*" /><conditions logicalGrouping="MatchAll" trackAllCaptures="false"><add input="{APP_WARMING_UP}" pattern="1" /></conditions><serverVariables><set name="SKIP_MANAGED_MODULES" value="0" /></serverVariables><action type="Rewrite" url="{URL}" /></rule><rule name="ARR_MyFarm_loadbalance" enabled="true" patternSyntax="Wildcard" stopProcessing="true"><match url="*" /><conditions logicalGrouping="MatchAll" trackAllCaptures="false" /><action type="Rewrite" url="http://MyFarm/{R:0}" /></rule></globalRules></rewrite>I don't use distributed rules defined in the web.config since they, as far as I know, are executed after global rules. And I need to disable the "farm" routing rule for initialization page. Tried to use Failed Request Tracing feature but
in the case of the application pool crash it doesn't create logs.
How can I configure warm up on the routing server to route to specific local page?