Application Initialization to warm up specific pages when app pool starts
I want to use IIS8's Application Initialization feature, but it has to be enabled in the Azure Websites VM first. I need this so I can warm up a list of individual pages before Azure declares the site fit for duty and directs traffic to it. The appropriate tool for this job is Application Initialization:
There are no good workarounds I'm aware of. I don't want to leav PaaS for Web Roles just for this. I've heard others suggest traffic monitoring or custom scripts, but none of those even have access to the target instance at that crucial moment--the minute before being added to load balancing or being swapped in as the active w3wp process. By the time my custom script hit a page, an unlucky customer would have already endured the cold start.
This idea received 98 votes and was marked Completed but it really only achieved half of what was asked for:
What was deliverd--warming up a stage site and having an instantaneous swap--is truly magnificent! It makes the deployment story excellent. BUT, there are plenty of reasons why I'd have apppool starts in production outside of my deployment process. In particular:
* Every time autoscale boots up another instance to add to the web farm
* Every time Microsoft rolls us onto a new instance for security updates or resource management
Using autoscale as it was intended with fluctuating traffic means several apppool starts every day! I want to warm these instances up just as thoroughly as I would my stage site during a deployment process. Hitting the home page isn't enough for my CMS powered site either. I've got a list of 30 maybe even 100 pages that I want to warm up before that app pool is considered ready for action in the web farm. Enough people had this same problem and that is why IIS8 has the Application Initialization feature baked in now.
Now we want it enabled and baked into the Azure Websites VM image too. We can configure it directly through web.config after that.
This needs to play well with the custom domains we've configured of course. Rules like these should work fine (meaning my.domain1.com is going to resolve to this exact IIS instance not reach out to the network and hit the load balancer):
<add initializationPage="/my-slow-the-first-time-page" hostName="my.domain1.com"/>
<add initializationPage="/another-slow-page-on-a-diff-domain" hostName="my.domain2.com"/>
And yes, improving page cold start times is a worthy goal and will be pursued too.
The Application Initialization (http://www.iis.net/downloads/microsoft/application-initialization) module has been implemented and is available to use for swap (http://ruslany.net/2015/09/how-to-warm-up-azure-web-app-during-deployment-slots-swap/).
It has also been implemented for all other operations in which a new worker is provisioned (such as auto scale, manual scale or Azure fabric maintenance).
Deployment is now complete.
Nir and the Web Apps team.
Curz Alan commented
I want to create an exception, to redirect Category like https://www.careerportal.com.ng/job-location/abuja to homepage. I'm really finding this difficult
Hi... I followed the blog at Ruslany. I was trying to create a redirect for a particular link on my website. I don't know if you can give me some hand.
I actually wants to redirect an absolute link to another link without redirecting other link extensions.
Now, when I implement the redirect rule at ruselany.net, it actually worked... but the challenge is, other url with /phone/*** also redirect to the above link.
but that is not what I want!
Please how do I correct the error?
So, I've been testing this and it appears IIS Application Initialization does not run at any of the times we would expect it to run.
With the Always On feature disabled (to stop that web request) the App Init URL does not run for any of these events:
-Performing a Stop & Start from the portal
-Performing a Restart from the portal
-Performing a manual scale from the portal
However, when Always On is _enabled_ the App Init URL does run for these events, but i'm guess only in response to the first web request - not proactively as it should.
Does App Initialization work for Azure App Services or not, how do you configure it?
We are trying to utilise this to warm-up our apps on scale-out as well as on a fresh deployment to the staging slot. Our deployments seem to work fine with warm up, however when we scale out we start to get responses from our API that indicate the scaled out application is responding before it has warmed up. Is there any specific config that is required for scale out or should the same config allow it to occur. Please see our question here: https://stackoverflow.com/questions/44652159/azure-website-warmup-on-scale-out
David Twamley commented
Tom, every instance is responsible for warming itself up and only ever talks to itself. Hostname is required, but it is only used as a header value, it is not even looked up in DNS and there is no outbound internet traffic because of it.
I use this feature on a multi-instance web app. When I manually scale up I can see it boot and warm the new instance before it starts sending it traffic. I hear it works the same for auto scale events although I haven't played with those. It also seems to honor the warm up when MS rolls you over to an upgraded VM where it boots the new instance, warms it up completely, and then sends traffic to it.
Tom Wilson commented
Is there still not a solution to hitting localhost? I have a multi-instance app that needs to hit localhost before a scale action happens, if i hit the main hostname, how do I ensure it's hitting the app that needs to be initialized?
Bryan Lewis commented
I just want to "third" the comment about supporting warm up behind forms authentication. Scale out is killing me because the new instances are cold.
As asked by Jean-Sébastien, how can we warm up pages behind authentication?
Right now we are doing this manually with swap with preview but this works only for swap and takes lot of times.
Also, it looks like we do not warm up all instances but just one, how can we manuallt warm up all instances?
Also learned the hard way - you MUST specify an actual hostname - even on application initialize, localhost is forbidden on Azure WebApps. This makes it only useful for deploying to 1 single website slot. So make it your production one, because all other slots it will fail.
FWIW, as we learned the hard way: This feature only honors the <applicationInitialization> section contained within the web.config of the '/' root web application. If you use virtual applications with their own web.config then the <applicationInitialization> section therein IS NOT used.
Since our solution does not use '/' and only contains virtual applications for API versioning (/versionX, /versionY) the approach we arrived at was to use a dummy web site app containing only a web.config containing the desired <applicationInitialization> section with initializationPage entries for each virtual app.
Jean-Sébastien Goupil commented
It is impossible to hit pages behind a login page. I have tried to use a WebSocket, fetch the CSRF, do a POST to login, get the cookie then start hitting pages with my cookie. This is what I get when it is being initialized (trying to hit http://localhost/Account/Login)
Unexpected Error in Application: System.Net.Sockets.SocketException (0x80004005): An attempt was made to access a socket in a way forbidden by its access permissions 127.0.0.1:80
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
The same code works great if the app is not being initialized.
What can we do here!?
@James, when you scale up/down, you change the 'size' of the underline VMs that are running your site(s). Scaling up, gives you more CPU, memory, disk, etc... Therefore, your site(s) are moved to a new set of VMs (larger in this examples) and therefore you see the 'new' machines across the board. essentially, your application is restarting on new VMs.
Scaling out, increasing your VM count but not changing the size of the VMs, gives you more new VMs. But the existing one remains active and can handle traffic.
If you are looking to scale UP (fresh set of VMs) and keep traffic, then you will need to explorer Traffic Manager. This will enable you to setup fresh new VMs (hosting Plan) and connect it to TM. You can warm up the VMs and then switch between the hosting plan. Your application will be warm and ready to handle traffic.
Hope this helps,
Hi, we've tested this on a live Azure website and seems to work exactly as required (i.e. scaling "out" and new instances not serving content until warmed up).
Thanks for implementing this, it's a great feature.
As part of our testing we thought we'd also test to see if "scaling up/down" might leverage this feature. It doesn't seem to do so though. I'm not sure how 'scaling up/down' works under the hood but it appears to immediately switch off the machine you are running on and then create a new machine according to the new spec (more RAM etc.). Would it be possible to keep the existing machine running on the existing spec and provision the new machine in the background? The new machine(s) would then warm up the websites using the "Application Initialization" settings and switch over once warm? Hence we could have scaling up and down with no outage experienced? There may be something I've not considered or understood here but that seems like another very desirable enhancement to the Azure Website service.
Please advise if this would be possible and something that could be implemented?
Is the scaling operations portion of the feature available yet?
Jean-Sébastien Goupil commented
I would indeed need this same feature, but with a little more configuration.
All my pages are behind a login/password form (with CSRF protection). So it would be interesting to support such scenario as well.
On a side note, is there somewhere I can look to see when the site is warming up, when the site is auto-swapping, and once auto-swap is a success/failure? Right now it hard to tell what stage its at. We use the new scripted build system to deploy to our azure web apps and use auto-swap to move from staging slot to production, but don't have any idea when the actual site is live or not.
We set this up a couple days ago and it was working. Now it doesn't seem to swap when I do a deployment. All I see is the msdeploy.axd call in the http logs which does the deploy but then I never see the SiteWarmup call that I used to.
While this works for Swap, the feature that will make this work for other situation (like scale events) is not quite complete. We will update when it is.
Graham Bunce commented
How does this answer the point well made above about non-swap situations? Am I missing something?
Very keen to see this implemented ASAP also.