首页 文章

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

提问于
浏览
9

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

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

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

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

3 回答

  • 1

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

    (编辑:我整理了一个简单的帮助程序类,它解决了标准的超时问题 - 基本上是Web应用程序"pokes"本身经常使进程保持活动状态 . 理想的方法是更改IIS中的设置,但对于不是这样的服务器可能,我的 class 运作得很好 . - Code at the bottom

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

    像往常一样,分析应用程序是获取具体信息的唯一方法 . 使用像ANTS这样的产品将帮助您确定应用程序花费最多时间在代码中的哪个位置,这样您就可以隔离"hang"发生的位置 .

    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/");
    
  • 0

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

    我写了一篇关于我使用它的经历的文章 .

  • 5

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

    更新:

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

相关问题