Azure Web Role "warm up" strategies
azure, azure-configuration, azure-web-roles, iis-8
Solution
We use a combination of a couple of those answers and it works perfectly well for us, they're very quick to change and test however, it seems to cover all bases.
public override bool OnStart()
{
ServicePointManager.DefaultConnectionLimit = 12;
if(!RoleEnvironment.IsEmulated)
{
using(ServerManager serverManager = new ServerManager())
{
foreach (var app in serverManager.Sites.SelectMany(x => x.Applications))
{
app["preloadEnabled"] = true;
}
foreach (var appPool in serverManager.ApplicationPools)
{
appPool.AutoStart = true;
appPool["startMode"] = "AlwaysRunning";
appPool.ProcessModel.IdleTimeout = TimeSpan.Zero;
appPool.Recycling.PeriodicRestart.Time = TimeSpan.Zero;
}
serverManager.CommitChanges();
}
}
return base.OnStart();
}
Problem
I found that making requests to our web role after periods on inactivity would result in a very slow request (up to 30 seconds). After that initial request, the role would perform as it should. After much Googling, I came across four different strategies (listed below): (a) Disabling IIS idle timeout in `RoleEntryPoint.OnStart()` ``` public override bool OnStart() { using (var server = new ServerManager()) { server.ApplicationPoolDefaults.ProcessModel.IdleTimeout = TimeSpan.Zero; server.CommitChanges(); } return base.OnStart(); } ``` This also requires that the role runs at an elevated level. (b) Perform regular requests in the `RoleEntryPoint.Run()` ``` public override void Run() { var localuri = new Uri(string.Format("https://{0}/Help", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["HttpsIn"].IPEndpoint)); while (true) { try { var request = (HttpWebRequest)WebRequest.Create(localuri); request.Method = "GET"; var response = request.GetResponse(); } catch { } System.Threading.Thread.Sleep(3000); } } ``` (c) Set `preloadEnabled` and `startMode` in the `RoleEntryPoint.OnStart()` ``` public override void OnStart() { using (var serverManager = new ServerManager()) { foreach (var application in serverManager.Sites.SelectMany(x => x.Applications)) { application["preloadEnabled"] = true; } foreach (var applicationPool in serverManager.ApplicationPools) { applicationPool["startMode"] = "AlwaysRunning"; } serverManager.CommitChanges(); } return base.OnStart(); } ``` (d) And lastly, using Azure's "Always On" (EDIT: This is only for Azure websites unfortunately!) Which of these strategies should I perform?