IIS Applications regelmäßig aufrufen und vor dem Shutdown/Restart bewahren


Wenn eine Webseite im IIS nicht regelmäßig aufgerufen wird, dann stoppt der IIS die Seite und die Seite muss beim nächsten aufrufen wieder neu gestartet werden. Leider kann der Neustart einer Webseite unter Umständen recht lang dauern, denn hier kommt es darauf an wie aufwendig z.B. der Application Start ist und ob auch der Applicationpool neugestartet werden muss.

Ab dem IIS 8.0 bietet Microsoft zwar die Möglichkeit das man einem Applicationpool mit der Erweiterung “Anwendungsinitialisierung” für den IIS so konfigurieren kann das der Applicationpool automatisch startet . Für die Webseiten ist mir dies bisher leider nicht gelungen. Das IIS Modul steht auch für den IIS 7.0/7.5 zur Verfügung.

image

In den erweiterten Applicationpool Einstellungen kann man dann den Startmodus des Applicationpools festlegen.

image

Auf Anwendungsebene gibt es dann in den Erweiterten Einstellungen die Option “Vorabladen aktiviert”.

image

Leider scheint es beim Vorabladen immer noch Probleme zu geben, vor allem wenn man bei seinen Webseiten Windows-Authentifizierung für den Login verwendet, scheint diese Variante zumindest mit IIS 7.X nicht zu funktionieren.

Eine alternative Lösung ist z.B. eine Konsolenanwendung die auf dem Server ausgeführt wird, auf dem die Webseiten im gehostet werden. Die Konsolenanwendung  wird in regelmäßigen Abständen aufgerufen und durchsucht den lokalen IIS nach allen Webseiten und ruft diese auf.

static void Main(string[] args)
{
    //Diese DLL einbinden für den ServerManager:
    //c:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll 

    //Servermanager verwenden um auf den lokalen IIS zuzugreifen
    ServerManager manager = new ServerManager();
    List<string> pages = new List<string>();

    // Die Auflistung aller Seiten auf dem Server ermitteln
    string sitedisplay = string.Empty;
    foreach (Site site in manager.Sites)
    {
        sitedisplay = sitedisplay + site.Name + ": ID= " + site.Id + "\n";
        string bindingdisplay = string.Empty;
        string port = string.Empty;
        string protokoll = "http";
        string host = "localhost";
        string appPath = string.Empty;

        foreach (Microsoft.Web.Administration.Binding binding in site.Bindings)
        {
            if (binding.EndPoint != null && (binding.Protocol == "http" || binding.Protocol == "https"))
            {
                bindingdisplay = "  Binding:";
                bindingdisplay += "\n   Host: " + binding.Host;
                bindingdisplay += "\n   Port: " + binding.EndPoint.Port;
                bindingdisplay += "\n   Protocol: " + binding.Protocol + "\n\n";

                port = binding.EndPoint.Port.ToString();
                protokoll = binding.Protocol;
                host = string.IsNullOrEmpty(binding.Host) ? "localhost" : binding.Host;
            }
        }

        foreach (Application app in site.Applications)
        {
            appPath = app.Path;
            //Alle Seiten URLs ermitteln
            var url = string.Format("{0}://{1}:{2}{3}", protokoll, host, port, appPath);
            pages.Add(url);
            Console.WriteLine(url);
        }

        sitedisplay = "\n" + sitedisplay + bindingdisplay;
    }

    Console.WriteLine(sitedisplay);
    
    //Callback Funktion für SSL-Zugriffe festlegen.
    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);

    //Alle Seiten die wir ermittelt haben mit einem WebRequest starten.
    //dieser WebRequest verwendet die Anmeldeinformationen der Konsolenanwendung.
    foreach (string page in pages)
    {
        Stopwatch stopwatch = new Stopwatch();
        try
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(page);
            request.Method = "GET";
            request.UseDefaultCredentials = false;
            request.PreAuthenticate = true;
            request.Credentials = CredentialCache.DefaultCredentials;
            Console.WriteLine("Page: {0} | Starting...", page);
            stopwatch.Start();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Console.WriteLine("Page: {0} | Status: {1}", page, response.StatusCode);
        }
        catch (Exception exception)
        {
            Console.WriteLine("Page: {0} | Status: {1} | Message: {2}", page, "Error", exception.Message);
        }
        finally
        {
            stopwatch.Stop();
            Console.WriteLine("Page: {0} | Startdauer: {1} ms \n\n", page, stopwatch.ElapsedMilliseconds);
        }
    }

    Console.WriteLine("DONE!");
    Console.ReadLine();
}

/// <summary>
/// Callback Funktion für SSL Aufrufe immer mit True bestätigen auch wenn das Zertifikat evtl. nicht valide ist. Für z.B. selbstsignierte Zertifikate im IIS
/// </summary>
public static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, 
                                           System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}

Wichtig ist das der Benutzer der die Konsolenanwendung ausführt als lokaler Administrator eingerichtet ist, denn die Anwendung greift auf den lokalen IIS zu. Außerdem muss der Benutzer als Domainuser eingetragen sein, wenn die Anwendung auch auf Webseiten zugreifen soll für die Windows-Authentifizierung eingerichtet ist.

Der Quellcode steht auch unter Codeplex zur Verfügung.

Advertisements

2 Gedanken zu „IIS Applications regelmäßig aufrufen und vor dem Shutdown/Restart bewahren

    1. SquadWuschel Autor

      Hallo,

      leider betrifft das nur den Applicationpool, dieser wird dann nicht mehr zurückgesetzt nach X Minuten. Ich habe aber nach einer Möglichkeit gesucht das meine Anwendung selbst nicht wieder zurückgesetzt wird, d.h. das der Application_Start meiner Anwendung nicht „ständig“ neu ausgeführt wird wenn die Seite mal eine Zeit lang nicht besucht wurde.

      Gefällt mir

      Antwort

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s