Donnerstag , 9 Juli 2020

Kombinieren von Web- und Worker Rollen in Windows Azure

Page BlobsIn diesem Blog Post möchte ich eine Grauzone der Windows Azure Cloud Services einmal genauer betrachten.
Es lassen sich nämlich die Funktionalitäten von Web- und Worker Rollen in eine gemeinsame Rolle vereinen.

Jetzt stellt sich natürlich die Frage, warum man so etwas machen sollte!?

Ein Grund hierfür wäre eine sich daraus ergebende Kostenersparnis, solange der Dienst noch nicht ausreichend ausgelastet ist.

Beispielsweise könnte man die 4 Rollen (2 Web- und 2 Worker Rollen), die mindestens nötig wären um das SLA von Microsoft zu erreichen, zu 2 kombinierten Web Rollen umwandeln.

Bevor ich allerdings auf die Umsetzung sowie deren Fallstricke eingehe, möchte ich erst einmal die “normale” Softwareentwicklung eines Windows Azure Cloud Services aufgreifen:

Unterschied zwischen Web- und Worker-Rollen

Die Cloud Services gehören zum Urgestein der Windows Azure Plattform.

Bei der Entwicklung eines Windows Azure Cloud Services stehen dabei 2 Vorlagen von Virtuellen Maschinen zur Verfügung:
Die Web Rollen und die Worker Rollen.

Der Hauptunterschied ist ein – bei den Web Rollen – vorinstallierter IIS.

Näheres zu der Erstellung einer Web Rolle hatte ich bereits in meinem Blog Post "Erste Schritte mit Windows Azure (Teil 1) – Die Web Rolle" veröffentlicht.

Auch wenn der Post leicht veraltet ist, hat sich nicht all zu viel zu heute verändert. 😉

Auf Grund des "fehlenden" IIS, sind die Worker Rollen vorwiegend für Hintergrund Aufgaben und Nicht-IIS-Dienste gedacht.

Um eine Worker Rolle zu implementieren, stellt die Visual Studio Projektvorlage dafür eine WorkerRole-Klasse bereit:

public class WorkerRole : RoleEntryPoint
{
  public override void Run()
  {
    // This is a sample worker implementation. Replace with your logic.
    Trace.TraceInformation("WorkerRole1 entry point called", "Information");

    while (true)
    {
      Thread.Sleep(10000);
      Trace.TraceInformation("Working", "Information");
    }
  }

  public override bool OnStart()
  {
    // Set the maximum number of concurrent connections 
    ServicePointManager.DefaultConnectionLimit = 12;

    // For information on handling configuration changes
    // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

    return base.OnStart();
  }
}

 

Diese von RoleEntryPoint abgeleitete Klasse bietet dabei 3 überbeschreibbare Methoden:

  • OnStart
    Diese Methode wird beim Start der Rolle aufgerufen
  • Run
    Diese Methode wird nach dem erfolgreichen Start der Rolle aufgerufen und enthält meist eine Endlosschleife.
  • OnStop
    Diese Methode wird aufgerufen, wenn die Rolle ein Signal zum Runterfahren erhalten hat.

 

Kombinieren zu einer gemeinsamen Web Rolle

Aber auch die Web Rollen stelle diese Klasse unter dem Namen WebRole zur Verfügung:

public class WebRole : RoleEntryPoint
{
  public override bool OnStart()
  {
    // For information on handling configuration changes
    // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

    return base.OnStart();
  }
}

 

Somit lässt sich also die gleiche Funktionalität einer Worker Rolle auch in eine Web Rolle implementieren.

Dazu erstellt man einen neuen Cloud Service …

Neuer Cloud Service

… und fügt die gewünschte Web Rolle hinzu.

Hinzufügen einer Web Rolle

Anschließend implementiert man das Web Projekt, sowie die Hintergrundfunktionalitäten mit Hilfe der WebRole-Klasse.

Wenn man diese kombinierte Web Rolle nun fertig implementiert hat, und sich per Remote Desktop Connection auf eine Instanz der Web Rolle verbindet, findet man auf dem Laufwerken E: bzw. F: (Dieses ändert sich bei jedem In-Place Update) folgende Verzeichnisstruktur:

Verzeichnisstruktur einer Web Rolle

Im siteroot-Verzeichnis werden die Web Projekte abgelegt, woraus sich der IIS bedient.

Das approot-Verzeichnis enthält eine Kopie des Hauptprojektes und wäre bei Worker Rollen der Dreh- und Angelpunkt der Instanz.

Aber – wie man sieht – ist das approot-Verzeichnis bei Web Rollen auch vorhanden.

 

Fallstricke

Wie Eingangs erwähnt ist die Verwendung dieser kombinierten Web-Rollen eher eine Grauzone bei der Cloud Services Entwicklung.

Ich vermute, dass die WebRole-Klasse noch eine Altlast darstellt, bevor es die Windows Azure Startup Tasks gab.

Deshalb möchte ich den gängigsten Fallstrick bei diesem Vorgehen kurz vorstellen.

Zugriff auf die Konfigurationsdatei

Wer in der WebRole-Klasse einmal versucht hat auf die Daten der web.config zuzugreifen – beispielsweise mit dem ConfigurationManager – wird festgestellt haben, dass er dabei ins Leere läuft.

Der Grund hierfür ist die fehlende Konfigurationsdatei im entsprechenden approot-Unterverzeichnis:

Fehlende Konfigurationsdatei

Um aber herauszufinden wie man das umgeht, sollte man sich die Funktionsweise des verantwortlichen Hintergrundprozesses anschauen.

Das Programm das bei den Web-Rollen diesen Hintergrundprozess ausführt ist die WaIISHost.exe:

WaIISHost.exe

Bei den Worker-Rollen ist dies übrigens die WaWorkerHost.exe

Leider haben sich dies aber über die bisherige Lebenszeit der Windows Azure Plattform auch die Internas dieses Prozesses geändert.

Anfangs konnte man eine eigene Konfigurationsdatei einschmuggeln indem man eine WaIISHost.exe.config Datei im Projekt anlegte.

Stand heute muss man eine Konfigurationsdatei anlegen, die den Namen des Projekt-Assemblies trägt.

Diese muss dann über die Datei-Eigenschaften im Projekt immer ins Ausgabe-Verzeichnis kopiert werden:

Datei-Eigenschaften der Konfigurationsdatei

Anschließend taucht diese dann im entsprechenden Verzeichnis auf …

… und kann von der WebRole-Klasse verwendet werden.

Dazu habe ich ein Beispielprojekt diesem Blog Post beigefügt.

Trace-Log des Beispielprojektes:

Emulatoransicht des Beispielprojektes:

 

Fazit

Mit Hilfe dieser kombinierten Web-Rollen lassen sich zwar am Anfang Kosten sparen, allerdings hat man einen Mehraufwand bei der Softwareentwicklung durch die Fallstricke und ggf. die spätere Trennung der Rollen.