This article will cover 9 things that are not mentioned in the documentation.
This is how the web.config applicationInitialization XML config can look like:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true"> <add initializationPage="/init1.aspx" hostName="somewebapp.azurewebsites.net"/> <add initializationPage="/init2.aspx" hostName="somewebapp.azurewebsites.net"/> </applicationInitialization> </system.webServer> </configuration>This config should be placed in the wwwroot.
What they don't mention in the documentation
1. You can have many initialization pages
As you can see in the example above you can actually initialize many pages e.g. init1.aspx, init2.aspx.2. Initializations are done in order
As per above example, init1.aspx will be called first, then as soon as init1.aspx responds or times out it will move on to init2.aspx3. Initializations are response ignorant
ApplicationInitilization doesn't care if init1.aspx returns 200, 404 or 503. As long as it returns something it will consider it's job done.This means if your init1.aspx page times out, IIS will still think that you are good to go.
4. Can't have duplicate initialization page
You can't have duplicate keys, such as:<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true"> <add initializationPage="/init1.aspx" hostName="somewebapp.azurewebsites.net"/> <add initializationPage="/init1.aspx" hostName="somewebapp.azurewebsites.net"/> </applicationInitialization> </system.webServer> </configuration>This will make IIS error. You might think, why on earth would you want to have duplicate keys? This could be considered a workaround for the timeouts, if init1.aspx takes too long to respond, call it again, next time hopefully it will respond immediately. To workaround this you could just add query string:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true"> <add initializationPage="/init1.aspx?call=1" hostName="somewebapp.azurewebsites.net"/> <add initializationPage="/init1.aspx?call=2" hostName="somewebapp.azurewebsites.net"/> </applicationInitialization> </system.webServer> </configuration>
5. Initializations are done internally
IIS applicationInitialization requests are done internally so you will not see them in your W3C logs. However if your init1.aspx page looks at the request and takes a look at the User Agent it will see the following: "IIS Application Initialization Preload"6. No client state is shared between calls
When IIS calls init1.aspx and then calls init2.aspx there is no common client state kept i.e. cookies, etc. This means you can't tag the IIS applicationInitialization client.7. Initialization can warm up virtual applications
8. hostName is the same for all slots
This has really surprised me, one Web App can have many slots, each slot has it's own name, however you when you use initializationPage you can just specify the main slots hostName and this will work for all slots. So for example, if you have production slot and you have staging slot you might consider doing something like this:Production Web.Confg
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true"> <add initializationPage="/init1.aspx?call=1" hostName="somewebapp.azurewebsites.net"/> <add initializationPage="/init1.aspx?call=2" hostName="somewebapp.azurewebsites.net"/> </applicationInitialization> </system.webServer> </configuration>Staging Web.Confg
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true"> <add initializationPage="/init1.aspx?call=1" hostName="somewebapp-staging.azurewebsites.net"/> <add initializationPage="/init1.aspx?call=2" hostName="somewebapp-staging.azurewebsites.net"/> </applicationInitialization> </system.webServer> </configuration>No need, this will work for both:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true"> <add initializationPage="/init1.aspx?call=1" hostName="somewebapp.azurewebsites.net"/> <add initializationPage="/init1.aspx?call=2" hostName="somewebapp.azurewebsites.net"/> </applicationInitialization> </system.webServer> </configuration>This is good news, as you will need to perform less transformations.
9. Load Balancer
This might be one of the most important points. IIS applicationInitialization and Azure Load Balancers work together. As soon as IIS initializes all of the pages, internal Azure Web Apps load balancer is notified and it starts sending traffic to the fully initialized instance. So you can use applicationInitialization to warm up your application completely before you allow traffic to come in.Conclusion
If you have a large app and you need to invoke many different areas to warm up caches, compilations, etc before your instance starts receiving traffic then IIS applicationInitialization is a good way to go!As I don't work for Microsoft I can't guarantee that my description of Azure Web App inner workings is 100% accurate.
Hi, first of all thanks for the post its clear and useful. Btw i want to know if point 9 its confirmed. I have an azure webrole application with a load balancer probe configured and im experiencing some problems when the service scales. It seems current running instances restart (1 by 1 -> ok) but they become on ready state before the loadbalncer probes returns 200. So incoming requests fail because cache is not ready and requests produces timeouts.
ReplyDeleteThanks in advance
Thank you for the comment! Point 9 is true for Azure Web Apps. I am not sure if it's true for other Azure services such as Azure Cloud Services.
DeleteThank you very much! This was really helpful. I could not find anywhere what to set as 'hostName' when working with Azure slots.
ReplyDeleteWhat does skipManagedModules="true" really do?
ReplyDeletePoint 8 is not true. I confirmed by starting weblogs and checking which paths were hit. When I add the production host name, the deployment slot name is never hit.
ReplyDeleteIn addition, if your code redirects from http to https (or with a rewrite rule in the web.config), the initialization will occur using http, which will return a 307. Since the initialization routine doesn't respond to http return codes, the page is never redirected to https. The solution is that you have to make sure your slot is set up to automatically redirect to https rather than using rewrite rules.