当访问时间很长时,保持ASP.NET IIS网站的响应

时间:2009-11-03 21:47:53

标签: .net asp.net iis

经过多年的ASP.NET开发,我真的很惊讶我似乎找不到令人满意的解决方案。

为什么IIS ASP.NET站点在一段时间不活动(几小时后)之后似乎总是睡着(2-6秒),在此期间没有HTTP响应从服务器发送到客户端。无论设置如何,这都发生在任何类型的站点上,一页或多页,db或不。我该如何解决这个问题?

在等待期间,服务器不忙,没有高峰或(.NET)内存短缺。我的猜测是,它与Windows将IIS进程移动到后台及其内存到页面文件有关,但我不确定。有人有什么想法吗?

编辑:一个解决方案是每小时左右发送一次HTTP请求,但我希望有更具建设性的内容。
编辑:我的意思是:在几小时不活动后,它会在任何新的HTTP请求上暂停几秒钟。

3 个答案:

答案 0 :(得分:6)

IIS的默认超时为20分钟。这意味着如果您的ASP.NET应用程序在20分钟内没有收到任何新请求,它将关闭工作进程。从零开始加热进程可能需要相当长的时间 - 将程序集加载到内存中,预编译等。

编辑:我整理了一个解决标准超时问题的简单帮助程序类 - 基本上,Web应用程序每隔一段时间就会自行调整一次以保持进程存活。理想的方法是更改IIS中的设置,但对于无法使用此功能的服务器,我的课程运行良好。 - 底部代码

虽然工作进程仍然存在,但不应该优先处理。当然不像你描述的那么快。您可以依赖于在非常短的时间内缓存的项目,并且在超过几秒钟未被请求时会丢失。如果不了解应用程序的详细信息,就无法说出来。

像往常一样,分析应用程序是获取具体信息的唯一方法。使用ANTS之类的产品可以帮助您确定应用程序花费最多时间在代码中的哪个位置,这样您就可以隔离出“挂起”的位置。

public class KeepAlive
{
     private static KeepAlive instance;
     private static object sync = new object();
     private string _applicationUrl;
     private string _cacheKey;

     private KeepAlive(string applicationUrl)
     {
         _applicationUrl = applicationUrl;
         _cacheKey = Guid.NewGuid().ToString();
         instance = this;
     }

     public static bool IsKeepingAlive
     {
         get
         {
             lock (sync)
             {
                 return instance != null;
             }
         }
     }

     public static void Start(string applicationUrl)
     {
         if(IsKeepingAlive)
         {
             return;
         }
         lock (sync)
         {
             instance = new KeepAlive(applicationUrl);
             instance.Insert();
         }
     }

     public static void Stop()
     {
         lock (sync)
         {
             HttpRuntime.Cache.Remove(instance._cacheKey);
             instance = null;
         }
     }

     private void Callback(string key, object value, CacheItemRemovedReason reason)
     {
         if (reason == CacheItemRemovedReason.Expired)
         {
             FetchApplicationUr();
             Insert();
         }
     }

     private void Insert()
     {
         HttpRuntime.Cache.Add(_cacheKey,
             this,
             null,
             Cache.NoAbsoluteExpiration,
             new TimeSpan(0, 10, 0),
             CacheItemPriority.Normal,
             this.Callback);
     }

     private void FetchApplicationUrl()
     {
         try
         {
             HttpWebRequest request = HttpWebRequest.Create(this._applicationUrl) as HttpWebRequest;
             using(HttpWebResponse response = request.GetResponse() as HttpWebResponse)
             {
                 HttpStatusCode status = response.StatusCode;
                 //log status
             }
         }
         catch (Exception ex)
         {
             //log exception
         }
     }
}

用法(可能在App_Start中):

KeepAlive.Start("http://www.yoursite.com/");

答案 1 :(得分:1)

如果你正在使用IIS 7,那么有一个IIS插件调用来自IIS团队的应用程序热备,这将有助于保持所有内容

我写了blog post关于使用它的经历。

答案 2 :(得分:0)

如果您目前仅编译代码,那么您可能还需要查看在complile time预编译您的aspx文件(而不是运行时,这是默认值)。我相信这个即时编译是大多数时候唤醒一个休眠的ASP.NET站点所占用的。您可以阅读更多相关信息here

更新

当达到IdleTime-Out值时,应用程序池被终止 - 默认为20分钟(您可以更改此值)。在这种情况下重启应用程序后,您确定UI没有重新编译吗? (我不确定它是否会强制重新编译UI。)