2017-12-20 10 views
1

Ich bin derzeit mit sehr lästigen Leistungsproblemen nach der Bereitstellung einer ASP.NET MVC4-Anwendung für Microsoft Azure. Unmittelbar nach dem Neustart der App (oder nach ein paar Minuten Inaktivität) dauert das Laden einiger Seiten etwa 15 Sekunden. Danach werden diese Seiten selbst beim Löschen des clientseitigen Cache in etwa 2 Sekunden geladen (was immer noch verbesserungsbedürftig ist, aber deutlich besser als 15 Sekunden, was ein großer Benutzererlebnis-Killer ist).ASP.NET MVC4 Seiten laden extrem langsam auf Microsoft Azure

Hier ist, was ich schon bisher versucht habe:

  • ich durch jedes Ereignis in Global.asax, um gekämmt zu Datenbank-bezogenen Code mit Dummy-Code
  • die veröffentlichen Ändern der Einstellungen zu ersetzen: «Precompile während der Veröffentlichung» (Merge alle Ausgänge auf einer einzigen Baugruppe)
  • nach Azure «App Performance Analysis» meine Anwendung betrachtet wird «gesund»
  • «Always On» ist innerhalb des Portals App-Einstellungen (Die Preisstufe aktiviert ist B1 [Basic, 1 Kern, 1 .75GB RAM], daher gehe ich davon aus, dass die Always-On-Schalter nicht durch die gemeinsame Laufzeitkonfiguration überschrieben bekommen)

Da keine der Kugeln über mein Problem gelöst habe ich versucht, einen keppalive-Job zu schreiben, mit Quartz.NET, die die Website wie dies regelmäßig Anfragen:

new System.Net.WebClient().OpenRead("https://foo.azurewebsites.net");

(In meinem Fall, ich glaube, der Effekt ist mehr oder weniger die gleichen wie initializationPages innerhalb Web.Config wie erwähnt here, erklärt nicht es?)

Die Ergebnis: Es funktioniert, aber nur für diese bestimmte URL. Eine Liste aller möglichen Routen zu führen, ist definitiv nicht der richtige Weg.

Haben Sie sich jemals mit diesem Problem beschäftigt? Ich würde Ihre Eingaben sehr schätzen!

Antwort

2

Es ist schon eine Weile her, dass ich in einer Organisation arbeitete, die auf Azure gehostet wurde, aber sie hatten eine Option, die man mit "Always On" konfigurieren konnte in einem Anwendungspool und halten Sie Ihre Anwendung in Arbeitsspeicher geladen. Ansonsten ohne Traffic wird Ihre Site entladen und beim ersten Treffer zum JIT gezwungen (ähnlich wie nach der ersten Deployment).

Ich habe gelesen über andere erstellen Mock HTTP-Anfrage an ihre Websites, um den Verkehr aufrecht zu erhalten und das Entladen aus dem Speicher zu vermeiden, wenn sie die niedrigeren Preise abonniert wurden, die nicht die "immer an" -Option angeboten.

Edit: Hier ist ein weiterer SO per Post adressieren: App pool timeout for azure web sites

+0

Vielen Dank für Ihre Eingabe. Ich habe vergessen zu erwähnen: Die Preisstufe der App ist B1 (weder ein kostenloser noch ein gemeinsamer Plan). Daher denke ich, dass in diesem Fall die "Always on" -Option tun sollte, was sie soll. Ist es nicht? Ich werde die Frage aktualisieren. Mocking HTTP-Anfragen ist genau das, was ich versuche zu vermeiden, da dies bedeuten würde, eine Liste von URLs zu pflegen. – Alan

+0

@Alan ... das ist die Antwort. Ich benutze es für genau Ihre Situation –

+0

Scheint so, als könnten wir nicht über HTTP-Anfragen für jede Seite spotten, um den JIT-Compiler zu zwingen, ihn aufzuwärmen, können wir? :) Ich werde eine neue Antwort posten, um die Lösung, mit der ich mich endlich zufrieden gab, im Detail zu erklären. Ich werde diese Antwort jedoch als die akzeptierte bezeichnen, da sie mich in die richtige Richtung führt. Danke an Travis & Big Daddy! +1 – Alan

0

Neben der akzeptierte Antwort, die ich im Detail erklären wollte, wie ich endlich mit diesem Thema befasst. Vielleicht kann dies in Zukunft jemand anderem helfen. Ich habe Code geschrieben, um die Anwendung beim Start zu starten, indem ich einfach eine Web-Anfrage auf kritischen Seiten auslöst (Ich habe die Erfahrung gemacht, dass dies für jede einzelne Seite getan werden muss. Das Aufwärmen der Stammadresse reicht nicht aus) .

private void WarmUp() 
{ 
    var baseUrl = "https://foo.azurewebsites.net"; 

    /** 
    * Requests to protected pages need to be authenticated and authorized, otherwise the JIT-Compile won't work 
    * For ASP.NET apps that are using FormsAuthentication just send a POST-request as you normally would do using a html form, 
    * then grab the cookie you get in the response and pass it to the subsequent requests 
    * */ 
    var email = "[email protected]"; 
    var password = "verysecure"; 
    var cookies = new CookieContainer(); 

    var webRequest = WebRequest.Create($"{baseUrl}/Account/Login") as HttpWebRequest; 
    webRequest.Method = "POST"; 
    webRequest.ContentType = "application/x-www-form-urlencoded"; 
    webRequest.CookieContainer = cookies; 

    var requestWriter = new StreamWriter(webRequest.GetRequestStream()); 
    requestWriter.Write($"user={email}&password={password}");//Small example for brevity. Don't forget to extract the requestVerificationToken in production :-) 
    requestWriter.Close(); 
    webRequest.GetResponse().Close(); 

    var urls = new[] { 
    baseUrl, 
    $"{baseUrl}/Home/Contact", 
    $"{baseUrl}/Protected/Stuff", 
    //... 
    }; 
    foreach (var url in urls)//trigger web-requests 
    { 
    webRequest = WebRequest.Create(url) as HttpWebRequest; 
    webRequest.CookieContainer = cookies; 
    webRequest.GetResponse().Close(); 
    } 
} 

Dies löst die zeitaufwändige JIT-Sachen für uns, wenn die App startet/nach der Bereitstellung, damit unsere Benutzer zu verhindern schreckliche Leistung zu erfahren, wenn die Seite anfordert.Wenn der Preisplan Ihrer App S1 oder höher ist, können Sie die Leistung mithilfe von deployment slots noch weiter verbessern. Mit ihnen können Sie die App vor der Bereitstellung in der Produktion aufwärmen.

In meinem Fall (reservierte Preisstufe, B1) denke ich, dass es ausreicht, den obigen Code einmal innerhalb von Application_Start auszuführen, da «Always on» verhindert, dass der Workerprozess meiner App automatisch heruntergefahren wird, falls die Site dies nicht tut Über einen bestimmten Zeitraum keine Zugriffe erhalten (Wenn Ihre App auf freigegebenen Ressourcen ausgeführt wird, stellen Sie sicher, dass Ihre App mit einem Cron-Job oder ähnlichem am Leben gehalten wird).