Troubleshooting App Initialization (IIS Warmup) on Azure Web Apps
Troubleshooting App Init (IIS Warmup)
Lately our team has been getting a higher load of issues related to customers trying to utilize the Application Initialization Module. This module is handy feature that allows you to warm your app prior to the application receiving requests to help avoid the dreaded cold-start or slow initial load times when the app is restarted. Common mistakes people run into and I’ll explain each one a little later:
- If your initialization page does some sort of redirect right away
- If your application requires HTTPS
The Application Initialization Module in IIS ONLY supports HTTP right now (I’ve created a feedback request for IIS to support this in the future). If you have a redirect to HTTPS due to authentication or following good practice to force users to use secure HTTPS connections to access your web app, the App Initialization will not behave as you’d expect. Let me explain – The way app initialization works is IIS sends a request to a specific page specified in your web.config. The out of the box implementation simply waits for any sort of response, no matter the status code. If I return a 401 (Unauthorized), 500 (Internal Server Error), or even a 302 (Redirect) IIS believes the app is ready to serve request and your initialization has completed therefore it will start sending requests to the process.
In scenarios where there is an overlapped recycle occurring or you have at least 2 instances for your App Service Plan you should almost no cold start because the FrontEnd load balancers in the infrastructure should not send requests to the “Workers” until the initialization completes.
Here’s another really good blog discussing how this works:
How to Setup the initialization in your web.config
I won’t go into much detail about the configuration of the App Init module since Ruslan covers this part in his blog below. Essentially you add this entry inside your web.config specifying the page(s) you want to warmup and the optional hostname.
<system.webServer> <applicationInitialization > <add initializationPage="/warmup-cache.php" hostName="appinit-warmup.azurewebsites.net"/> </applicationInitialization> <system.webServer>
Built in App Initialization for slot swaps
For the App Service auto swap feature, there is a built in mechanism to utilize the application initilization module without any changes to your web.config. See the doc below for more details.
How to Troubleshoot
These calls are not logged in the IIS Logs so the only way to track down if the initialization is performing correctly is to utilize Failed Request Tracing (FREB). My example below consists of a simple php page that sleeps 10 seconds.
- Enable Failed Request Tracing (Freb) from the Azure Portal
- Add the bolded portion to your web.config. In the add path section add in the specific warmup page. This will help reduce the number of logs FREB creates and will capture any status code that the request returns.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> </system.web> <system.webServer> <applicationInitialization > <add initializationPage="/customwarmup.php"/> </applicationInitialization> <tracing> <traceFailedRequests> <clear/> <add path="/customwarmup.php"> <traceAreas> <add provider="ASP" verbosity="Verbose" /> <add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" /> <add provider="ISAPI Extension" verbosity="Verbose" /> <add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,Rewrite,iisnode" verbosity="Verbose" /> </traceAreas> <failureDefinitions statusCodes="200-600" /> </add> </traceFailedRequests> </tracing> </system.webServer> </configuration>
- Initiate the swap
- Navigate to Kudu (appname.scm.azurewebsites.net)-> D:/home/Logfiles/W3SVCxxxx
- Click on the Download link and find the request that has the path of your initialization process and the User_agent IIS Application Initialization Warmup.
- Validate the response is what the HTTP status code, most likely a 200 with the respective time taken.
An example of an unexpected result when I added an entry in my web.config to force HTTPS – The response here is a 301 after 1015 so my initialization page would not have correctly warmed up my application.