在Azure上增加AppPool超时的优点/缺点

时间:2011-12-29 21:32:41

标签: asp.net asp.net-mvc-3 iis azure

我正准备将我的ASP.NET MVC3网络应用程序投入生产,但是,作为一个复杂的应用程序,启动需要 LONG 时间。显然,我不希望我的用户在AppPool超时后第一次请求时等待一分钟。

根据我的研究,我发现有两种方法可以解决这个问题:

运行职员角色或其他流程 - 每隔19分钟对该网站进行一次民意调查,以防止热身。

将超时从默认的20分钟更改 - 更大的东西。

由于解决方案2似乎是更好的主意,我只是想知道这会有什么缺点,我会耗尽内存等吗?

感谢。

3 个答案:

答案 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保留那些拥有大量轻易使用的网站的服务器所不需要的资源。鉴于使用频繁的网站(比如这个!)没有关闭他们的工作流程,我认为你不会看到任何内存问题。