我正准备将我的ASP.NET MVC3网络应用程序投入生产,但是,作为一个复杂的应用程序,启动需要 LONG 时间。显然,我不希望我的用户在AppPool超时后第一次请求时等待一分钟。
根据我的研究,我发现有两种方法可以解决这个问题:
运行职员角色或其他流程 - 每隔19分钟对该网站进行一次民意调查,以防止热身。
将超时从默认的20分钟更改 - 更大的东西。
由于解决方案2似乎是更好的主意,我只是想知道这会有什么缺点,我会耗尽内存等吗?
感谢。
答案 0 :(得分:3)
您可以使用IIS的自动启动功能吗?有一篇文章here提出了这个想法。
您拥有Azure OS系列2的IIS 7.5和Win2k8 R2。您只需要能够编写脚本/自动执行任何设置步骤和配置。
答案 1 :(得分:2)
我使用后台线程执行此操作,该后台线程每15分钟请求一个keepalive URL。这不仅可以防止应用程序空闲,而且还可以在Web角色或虚拟机重新启动或重建时立即加热应用程序。
这一切都是可能的,因为Web角色真的只是工作者角色,也是IIS的东西。因此,您仍然可以在Web角色中使用所有标准的Worker Role启动挂钩。
我从this blog post得到了这个想法,但调整了代码以做一些额外的预热任务。
首先,我有一个继承自RoleEntryPoint的类(除了这个热身任务之外还做了一些其他的事情,为了简单起见我删除了它们):
public class WebRole : RoleEntryPoint
{
// other unrelated member variables appear here...
private WarmUp _warmUp;
public override bool OnStart()
{
// other startup stuff appears here...
_warmUp = new WarmUp();
_warmUp.Start();
return base.OnStart();
}
}
所有实际的预热逻辑都在此WarmUp类中。当它第一次运行时,会在本地实例IP地址(与公共负载平衡主机名相比)上访问少量URL,以便在内存中获取内容,以便第一批使用它的人获得最快的响应时间。然后,它循环并命中单个keepalive URL(再次在本地角色实例上),该URL不执行任何工作,只是用于确保IIS不会将应用程序池关闭为空闲。
public class WarmUp
{
private Thread worker;
public void Start()
{
worker = new Thread(new ThreadStart(Run));
worker.IsBackground = true;
worker.Start();
}
private void Run()
{
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["http"]; // "http" has to match the endpointName in your ServiceDefinition.csdef file.
var pages = new string[]
{
"/",
"/help",
"/signin",
"/register",
"/faqs"
};
foreach (var page in pages)
{
try
{
var address = String.Format("{0}://{1}:{2}{3}",
endpoint.Protocol,
endpoint.IPEndpoint.Address,
endpoint.IPEndpoint.Port,
page);
var webClient = new WebClient();
webClient.DownloadString(address);
Debug.WriteLine(string.Format("Warmed {0}", address));
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
var keepalive = String.Format("{0}://{1}:{2}{3}",
endpoint.Protocol,
endpoint.IPEndpoint.Address,
endpoint.IPEndpoint.Port,
"/keepalive");
while (true)
{
try
{
var webClient = new WebClient();
webClient.DownloadString(keepalive);
Debug.WriteLine(string.Format("Pinged {0}", keepalive));
}
catch (Exception ex)
{
//absorb
}
Thread.Sleep(900000); // 15 minutes
}
}
}
答案 2 :(得分:1)
就个人而言,我会更改超时,但两者都应该有效:有效的是它们都会阻止工作进程关闭。
我认为超时是为了避免IIS保留那些拥有大量轻易使用的网站的服务器所不需要的资源。鉴于使用频繁的网站(比如这个!)没有关闭他们的工作流程,我认为你不会看到任何内存问题。