Startet man eine ASP.NET Anwendung zum ersten Mal, kommt man nicht gerade in einen Geschwindigkeitsrausch. Dies liegt zum Beispiel daran, dass der IIS den ASP.NET Worker Prozess hochfahren muss. Außerdem läuft eventuell im Ereignis Application_Start hinterlegter Initialisierungscode und schließlich müssen die vorliegenden Assemblies noch durch den JITer in nativen Code überführt werden.
All dies führt dazu, dass man relativ selten so etwas wie “rasend schnell” hört, wenn vom ersten Zugriff auf eine ASP.NET Anwendung gesprochen wird.
Glücklicherweise ist all dies nach dem ersten Request einer Seite kein Problem mehr. Der Worker Prozess ist da, der Initialisierungscode lief und die Just In Time Compilation lief auch.
Zu einem Problem wird die Situation jedoch, wenn man seine ASP.NET Anwendung während der Entwicklung als ein Bestandteil des Nightly Builds automatisch deployed und auch seinem Kunden Zugriff auf diesen täglich frischen Applikationsstand gibt.
Da Kunden morgens nämlich meist früher als Entwickler im Büro sind, sind sie auch die ersten, die die Webanwendung öffnen, um zu sehen, was am Vortrag umgesetzt wurde. Ist dieser erste Zugriff nun aus den oben genannten Gründen langsam, ist negatives Feedback des Kundens zur Applikationsperformance - oder sogar noch schlimmer: im Stillen sinkendes vertrauen in Applikation und Entwickler nicht selten die Folge.
Um dieses Problem zu umgehen, habe ich ein kleines Powershell Script geschrieben, das nach Angabe einer URL die einzelnen Seiten einer Webapplikation ansurft.
function warmup-site( [string] $rootUrl){
$proxy = New-Object System.Net.WebProxy("mein.firmen.proxy:8080")
$proxy.UseDefaultCredentials = 1
$wc = New-Object System.Net.WebClient
$wc.Proxy = $proxy
$pages = @("default.aspx", "seite1.aspx", "seite2.aspx", "subfolder/seite3.aspx")
# Jede Seite 3 Mal ansurfen, um Sie "warmzuklicken"
for ($i=0; $i -lt 3; $i++){
foreach($page in $pages){
trap [System.Net.WebException] {
write-error $("TRAPPED: " + $_.Exception.ToString());
continue;
}
$content = $wc.DownloadString($rootUrl+$page)
write $("URL " + $rootUrl+$page + " angesurft");
}
}
}
warmup-site("http://meine.url/")
Bisher gebe ich die einzelnen Seiten die angefragt werden sollen noch manuell innerhalb des Arrays $pages an. Im nächsten Schritt würde ich jedoch lieber nur noch die URL der Sitemap angeben, diese auslesen und dann sämtliche in der Sitemap aufgeführten URLs anfragen. Da ich jedoch noch Powershell Neuling bin, könnte es noch ein wenig dauern, bis ich die Lösung so weit automatisiert habe. Sollte einer der Leser nun sagen: “Das ist doch ein Dreizeiler, den ich in der Kaffeepause aus dem Ärmel schütteln könnte”, dann würde ich darum bitten genau diesen Dreizeiler über die Kommentarfunktion meines Blogs hier einzustellen ;-)
Was bringts?
Die Anwendung startet beim ersten Request nun bedeutend schneller. Somit ist der Kunde beruhigt und wir können uns auf die wichtigen Sachen des Projekts konzentrieren ;-)
Habe übrigens gesehen, dass es ab dem IIS 7 (oder 7.5?) von Hause aus eine Warmup gibt. Hat jemand von euch Erfahrung damit? Im Moment ist es für mich zwar noch nicht akut, da wir den IIS 6 nutzen, wäre aber Interessant für die Zukunft ein paar Erfahrungsberichte zur Hand zu haben.
Es gibt 1 Kommentare