2009-11-03 3 views
9

Nach Jahren der ASP.NET-Entwicklung bin ich eigentlich ziemlich überrascht, dass ich keine befriedigende Lösung dafür finden kann.Halten Sie eine ASP.NET IIS-Website ansprechend, wenn die Zeit zwischen den Besuchen lang ist

Warum scheint eine IIS ASP.NET-Site immer nach einer bestimmten Inaktivitätszeit (nach mehreren Stunden) (während 2-6 Sekunden) einzuschlafen, während der keine HTTP-Antwort vom Server an den Client gesendet wird. Dies geschieht unabhängig von den Einstellungen auf jeder Art von Site, einer Seite oder mehreren, db oder nicht. Wie kann ich das beheben?

Während der Wartezeit ist der Server nicht ausgelastet und es gibt keine hohen Spitzen oder (.NET) Speichermangel. Meine Vermutung ist, es hat damit zu tun, dass Windows den IIS-Prozess in den Hintergrund und seinen Speicher in die Auslagerungsdatei verschiebt, aber ich bin mir nicht sicher. Hat jemand eine Idee?

BEARBEITEN: eine Lösung ist es, eine HTTP-Anfrage einmal die Stunde oder so zu senden, aber ich hoffe auf etwas konstruktiveres.
EDIT: was ich meinte ist: nach Stunden der Inaktivität pausiert es einige Sekunden bei jeder neuen HTTP-Anfrage.

+0

+1, aber gehört zu serverfault. –

+0

Kompilieren Sie Ihre Site? Wenn nicht, verpasst du einige sehr große Leistungsverbesserungen. – codethrift

+0

@theminesgreg: Websites sind kompiliert, Debug ist nicht festgelegt, Optimierungen sind für die (alle) DLLs aktiviert. @John: Nicht sicher, dass es auf Serverfault gehört, da dies mich als Programmierer wirklich beunruhigt, aber korrigieren Sie mich, wenn ich falsch liege – Abel

Antwort

5

Das Standardzeitlimit für IIS beträgt 20 Minuten. Das bedeutet, wenn Ihre ASP.NET-Anwendung 20 Minuten lang keine neuen Anforderungen erhält, wird der Worker-Prozess beendet. Es kann eine beträchtliche Menge an Zeit in Anspruch nehmen, den Prozess aus dem Nichts zum Aufwärmen - Ladeeinheiten in dem Speicher, Precompilieren usw.

(bearbeiten: Ich habe eine einfache Hilfsklasse, die das Standard-Timeout Problem behebt - im Grunde des Web-Anwendung "pokes" sich selbst so oft, um den Prozess am Leben zu halten. Der ideale Ansatz ist es, die Einstellung in IIS zu ändern, aber für Server, wo dies nicht möglich ist, funktioniert meine Klasse ziemlich gut. Code an der Unterseite)

Während der Arbeitsprozess noch am Leben ist, sollte es nicht degriorisiert werden. Sicherlich nicht so schnell wie du es beschreibst. Es ist möglich, dass Sie sich auf Objekte verlassen können, die für einen sehr kurzen Zeitraum zwischengespeichert werden, und dass sie ausfallen, wenn sie nicht länger als ein paar Sekunden angefordert wurden. Ohne mehr über die Einzelheiten Ihrer Bewerbung zu wissen, ist das unmöglich zu sagen.

Wie üblich ist das Profilieren Ihrer Anwendung die einzige Möglichkeit, konkrete Informationen zu erhalten. Wenn Sie ein Produkt wie ANTS verwenden, können Sie feststellen, wo im Code Ihre Anwendung die meiste Zeit verbringt, damit Sie isolieren können, wo das "Hängen" auftritt.

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 
     } 
    } 
} 

Usage (vielleicht in App_Start):

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

Sie zeigen auf einige interessante Gedanken. Ich nahm immer an, dass es nie zum 'Application_Start' gekommen ist, aber was weiß ich, vielleicht kommt es dorthin, lädt libs usw. und setzt dann fort. Bitte beachten Sie, dass die Zeit nicht 20 Minuten (Session-Timeout-Zeit) beträgt, es dauert nach ca. 3+ Stunden etwas an, aber ich bin mir nicht sicher. Die Zeit kann variabel sein. Es ist nicht nur "eine Seite", sondern "alle Seiten" auf vielen Systemen und IIS/Windows-Versionen. Alle sind jedoch .NET 3.5. – Abel

+0

Am * "aber was weiß ich" * >>> soll sagen: Ich sollte einloggen oder Trace einschalten oder was auch immer. Ich kenne ANTS, aber ich bin mir nicht sicher, ob es hier helfen kann: Die Blockierung scheint zu passieren, bevor irgendetwas geladen ist, was ANTS beinhalten würde. – Abel

+0

Gerade bemerkt gleichen Kommentar hier http://www.eggheadcafe.com/software/aspnet/30548981/slow-site-startup.aspx, die dieses Leerlauf-Timeout erwähnt. Es passiert nicht lokal, nur remote auf Konfigurationen, die ich nicht immer verwalte. Es sollte nicht lange dauern, um herauszufinden, ob alles in dieser Einstellung ist. – Abel

1

Wenn Sie mit IIS 7 gibt es eine IIS Plugin-Aufruf Anwendung Up vom IIS-Team warm, dass alles, was auf keinen Fall kalt

halten helfen

Ich habe eine blog post über meine Erfahrungen damit geschrieben.

+1

Interessantes Plugin. Außerdem kann das 20-Minuten-Zeitlimit für den Anwendungspool festgelegt werden. Ich setze es auf 24 Stunden auf den meisten Servern, was hilft (PS: Ihre Website reagiert nicht ...) – Abel

+0

Hilarious - ich nehme an, der Blog wurde neu erstellt haha ​​- wie ironisch – Doug

0

Wenn Sie nur Ihren Code im Moment kompilieren, dann möchten Sie vielleicht auch Vor-kompilieren Ihrer Aspx-Dateien zur Complile-Zeit (anstatt Runtime, die die Standardeinstellung ist). Ich glaube, dass diese On-The-Fly-Kompilierung die meiste Zeit beansprucht, wenn eine ruhende ASP.NET-Site geweckt wird. Sie können mehr darüber lesen here.

Update:

Der Anwendungspool getötet wird, wenn der IdleTime-Out-Wert erreicht ist - diese standardmäßig auf 20 Minuten (Sie können diesen Wert ändern). Sind Sie sicher, dass die Benutzeroberfläche in diesem Fall nicht neu kompiliert wird, nachdem die App neu gestartet wurde? (Ich bin mir nicht sicher, ob es eine UI-Neukompilierung erzwingt oder nicht).

+0

Während Ihre Aussage korrekt ist, passiert das Kompilieren von Seiten nur einmal , auch wenn Sie keine Vorkompilierung wählen (was ich bevorzuge, wenn ich ein Mitspracherecht in einem Projekt habe). Das in der Frage erwähnte Problem wird nach 20 Minuten Inaktivität verursacht und könnte als "Schlafmodus" des Anwendungspools betrachtet werden. Überprüfen Sie Ihre Protokolle, wenn Sie eine kleine lokale Website haben: Wenn die ersten Kunden um 4 Uhr morgens ankommen, sehen Sie eine lange Wartezeit für die allerersten Anfragen. – Abel

+0

Welche Version von IIS verwenden Sie? und haben Sie Administratorzugriff auf IIS? – UpTheCreek

Verwandte Themen