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?
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();
}
Have you considered using the Azure endpoint monitoring to both monitor and trigger your role to respond every 5 minutes? It's built into Azure and there's no code needed.
http://azure.microsoft.com/en-us/documentation/articles/web-sites-monitor/
来源:https://stackoverflow.com/questions/24676194/azure-web-role-warm-up-strategies