none
Queue für WorkerRole?

    Frage

  • Hi,
    ich habe ein WorkerRole Service lokal bereit gestellt, und über den Endpunkt Tcp mit Hilfe des WCF bestimmte Funktionen aufzurufen.
    Es scheint so, dass die WorkerRole schon eine Queue vorhanden haben? Ich habe die Funktionaufruf als Excel-Funktion 1000 Calls aufgerufen. Die Funktion sollte mir eine Latenzzeit zurückgeben, komischerweise bekomme ich oft die "0" als Antwort zurück.
    WCFWorkerRoleServerClient_Bib.WFCWorkerInterfaces.IWCFWorkerRoleServerClient client = GetAProxy();
    
    var start = Environment.TickCount;
    client.GetLatenz();
    return Environment.TickCount- start;
    2 Frage hätte ich, brauche eine Queue für WorkerRole, wenn man mehere WorkerRole-Instanzen haben? Oder kümmert sich Azure schon drum?
    Warum bekomme ich ab und zu die "0" zurück, ich rechne mit Milisekunden und lasse die WorkerRole auf dem Emulator simulieren.

    Mit freundlichen Grüßen
    Cheng Trong-Nghia

    Dienstag, 13. November 2012 10:28

Antworten

  • Hallo Nghia,

    den "dummyPoint" brauchst du gar nicht. Im Grunde reicht ein Port (z.B. bei Dir Port 19). Wenn ein Client eine Anfrage auf diesem Port und der Adresse Deines Cloud Service (<servicename>.cloudapp.net) absetzt, dann kommt diese Anfrage erst mal noch nicht bei einer Instanz an sondern beim Loadbalancer. Der Loadbalancer verteilt nun alle eingehenden Nachrichten auf die Instanzen. Die jeweiligen Instanzen empfangen die Nachrichten also sozusagen vom Loadbalancer und zwar auf ihrem eigenen Port 19 (in jeder Instanz ist bei deiner Konfiguration oben Port 19 zum Empfang geöffnet). Optional könntest Du für Endpunkte auch interne Ports definieren, d.h. der Loadbalancer empfängt auf Port X, er leitet aber Anfragen an die Instanzen auf deren Port Y.

    Es ist also egal wie viele Instanzen gerade laufen, der Loadbalancer kennt sie alle und verteilt Anfragen an alle. Er passt sich auch dynamisch an Änderungen der Instanzen an. Das macht es auch möglich, zur Laufzeit Instanzen dazu zu schalten oder wegzunehmen ohne an der Port-Konfiguration was zu ändern. Das wird alles von Azure übernommen.

    Das Beispiel, das ich Dir oben geschickt hatte, hat zwei Ports geöffnet, weil für manche Aufrufe von den Clients der eine Port, für andere der andere Port verwendet wird.

    Ja, CloudBerry Explorer ist auch prima.

    Viele Grüße und ein schönes Wochenende,

    Holger


    Holger Sirtl Senior Technical Evangelist, Microsoft Deutschland GmbH http://blogs.msdn.com/hsirtl

    Freitag, 16. November 2012 14:38
  • Hi Nghia,

    vielen Dank :)

    Ich denke, die Konfiguration von Gladinet ist viel einfacher: der Endpunkt (also das, was Du in Gladinet unter "Account Name (Endpoint)", den Du brauchst, ist einfach der URL-Bestandteil, der vor blob.core.windows.net steht. In meinem Beispiel (siehe Abbildung hier) ist das also "hsirtl".

    Über den Button "Schlüsselverwaltung" bekommst Du Zugriff auf den Schlüssel, den Du in Gladinet als "Primary Access Key" angeben musst. Hier das Fenster der Schlüsselverwaltung:

    Für die Konfiguration von Gladinet brauchst Du also die beiden rot umrandeten Werte in obiger Abbildung).

    Einen Loadbalancer für WorkerRoles musst Du gar nicht implementieren. Der wird vollautomatisch von Azure konfiguriert, sobald für Deine Rollen einen Kommunikationsport in der *.csdef öffnest. Hier ein Beispiel:

    <?xml version="1.0" encoding="utf-8"?>

    <ServiceDefinition name="FTP2Azure" ...>

      <WorkerRole name="FTPServerRole">

        <Endpoints>

          <InputEndpoint name="FTP" port="21" protocol="tcp" />

          <InputEndpoint name="FTPPASV" protocol="tcp" port="59860" />

        </Endpoints>

        ...

      </WorkerRole>

    </ServiceDefinition>

    Das ist aus einem Blog, den ich diese Woche zum Thema "FTP-Zugriff auf Windows Azure Blob Storage" geschrieben habe. Dort werden für eine Worker Role zwei TCP-Ports geöffnet: Port 21 und Port 59860. Wenn jetzt mehrere Worker Roles gestartet werden, werden alle Zugriffe von außen zu einem der Ports automatisch auf die Worker Roles verteilt.

    Eine Queue macht dann Sinn, wenn Du Deine WorkerRole-Aufrufe asynchron durchführen möchtest bzw. kannst. Bei einem direkten WorkerRole-Aufruf wartest Du in Deinem Client ja in der Regel darauf, dass die Verarbeitung durch die WorkerRole abgeschlossen wird. Wenn das schnell geht (also beispielsweise eine Berechnung durchgeführt wird, auf deren Ergebnis Du wartest), ist das auch okay so (obwohl man Aufrufe ins Internet idealerweise immer asynchron implementieren sollte, damit der Client nicht blockiert wird, wenn bei der Netzverbindung etwas schief läuft). Wenn Du aber größere Arbeitsaufträge für die WorkerRoles hast (z.B. Video-Konvertierung), wäre es besser, Dein Client stellt einfach eine Nachricht mit einem Arbeitsauftrag in eine Queue. Dann kann Dein Client weiterarbeiten. Im Hintergrund liest dann eine verfügbare WorkerRole den Arbeitsauftrag aus und macht sich an die Verarbeitung. Dann stellt sich natürlich die Frage, wie Dein Client über den Abschluss der Verarbeitung bzw. das Ergebnis informiert wird. Ggf. kann der Client auch einfach immer wieder dort nachsehen wo WorkerRoles das Ergebnis hinschreiben (z.B. Blob Storage).

    In Deinem Fall brauchst Du bei den Annahmen, die Du oben schreibst, also nicht unbedingt eine Queue.

    Viele Grüße,

    Holger


    Holger Sirtl Senior Technical Evangelist, Microsoft Deutschland GmbH http://blogs.msdn.com/hsirtl


    Freitag, 16. November 2012 09:47

Alle Antworten

  • Hi,

    ich bin nicht ganz sicher, ob ich die Problemstellung richtig verstehe. Ein paar Rückfragen hätte ich:

    • Heißt "lokal bereitgestellt" soviel wie "im Windows Azure Emulator"?
    • Ist mit Queue eine "Windows Azure Storage Queue" oder eine "Windows Azure Service Bus Queue gemeint"?
    • Stammt der Code oben aus der Excel-Funktion?
    • Warum wird für die Server Funktionalität eine Worker Role und nicht eine Web Role verwendet?
    • Verstehe ich das richtig? Eine Excel-Funktion soll Nachrichten in eine Queue einstellen, und mehrere WorkerRoles sollen diese Nachrichten abarbeiten?

    Grundsätzlich müssen Queues (egal ob Storage Queues oder Service Bus Queues) erst gezielt angelegt werden, d.h. Azure kümmert sich nicht automatisch darum (wie auch? Azure "weiß ja nicht", dass Queues verwendet werden sollen). Es können sich aber viele Empfänger eine Queue teilen. Das ist auch explizit so vorgesehen, da hierüber die Worker-Prozesse einfach skaliert werden können. Wenn also viele Nachrichten in eine Queue eingestellt werden, können auch viele Worker-Prozesse gestartet werden, um die Nachrichten abzuarbeiten.

    Viele Grüße,

    Holger Sirtl


    Holger Sirtl Senior Technical Evangelist, Microsoft Deutschland GmbH

    Mittwoch, 14. November 2012 10:27
    • Ja, lokal heißt "im Windows Azure Emulator"
    • Mit der Queue meinte ich nur die Warteschlange (im Storage)
    • Das ist ein normale .NET Code. Bei Aufruf einer Excel-Funktion(=AzureFunktion()) wird dieses Code einmal ausgeführt
    • Wir brauchen keine WebDarstellung, hat Web Role den Worker Role andere Besonderheiten?
    • Ja, vorerst. Später sollen die Parameter in einem BLOB-Storage reingelegt werden. (weil die Queue nur 64kb groß sein darf?)

    Ich habe mit Excel, 1000 Anfragen an Worker Role geschickt, Excel führt die Excel-Funktionen asynchron aus. Ich verstehe so, dass das Worker Role Services alle Anfrage annimmt und gleichmäßig auf die Instanzen verteilt? Oder arbeitet nur 1 von 5 Instanzen (bei einem Worker Role), wenn ich keine queue benutze?

    Wie kann ich ein Client (z.B. WindowForm) schreiben, sodass ich die Azure Storage benutzen kann? Oder noch besser, kann ich BLOB-Storage als lokale Laufwerk einbinden?

    Viele Grüße

    Nghia

    Mittwoch, 14. November 2012 13:03
  • Hallo Nghia,

    von außen (also von Excel) können Nachrichten an Worker Roles nur dann geschickt werden, wenn entsprechende Empfangsports definiert und geöffnet wurden. Das passiert in der Datei *.csdef. Wenn Du dort einen Port angibst, wird beim Deployment des Cloud Service (bzw. der Worker Role) ein Loadbalancer konfiguriert, der empfangene Nachrichten automatisch gleichmäßig an alle Instanzen der Worker Role verteilt. Bei Web Roles musst Du nichts konfigurieren, weil da Port 80 bereits für http-Requests geöffnet ist.

    In Deinem Fall verstehe ich es aber so, dass Du die Nachrichten nicht direkt an die Worker Roles sondern an eine Queue schickst, oder? Dann ist es so, dass immer die nächste verfügbare Worker Role eine Nachricht aus der Queue ausliest und verarbeitet. Ich habe vor einiger Zeit zum Queue Storage ein Youtube-Video veröffentlicht, in dem ich den Mechanismus des Queue Storage erkläre

    Es ist eigentlich gar kein Problem, einen lokalen Client zu schreiben, der Queue Storage benutzt. Es gibt einen englischen Thread, der den Code für ein Beispielprogramm enthält. Du musst nur die entsprechenden .NET-Bibliotheken aus dem Windows Azure SDK in Deine Anwendung mit aufnehmen.

    Ja, Blob-Storage lässt sich als lokales Laufwerk einbinden. Hierzu gibt es eine Partner-Lösung der Firma Gladinet: Cloud Desktop. In einer Starter Edition ist sie sogar kostenlos. Lässt sich sehr einfach installieren und zum Einsatz mit Blob Storage konfigurieren:

    Danach hat man im Explorer ein neues Laufwerk, auf das man ganz normal zugreifen kann, hinter dem aber dann Blob Storage steckt.

    Viele Grüße,

    Holger


    Holger Sirtl Senior Technical Evangelist, Microsoft Deutschland GmbH http://blogs.msdn.com/hsirtl

    Donnerstag, 15. November 2012 09:07
  • Hi Holger, deine Videos sind immer sehr hilfreich, ein persönliche Dank von mir.

    Das Gladinet habe ich gestern ausprobiert, aber ich kriege Probleme beim Login, weil mein Endpoint im Storage nicht erscheint. Jedes mal, wenn ich auf Endpoint klicke, dann wird ausschließlich "Blobs->Queues->Tables" in "Tables->Queues->Blobs" umsortiert???? (lieg es an die Testphase?)

    Ein Client für Worker Role habe bereits umgesetzt mit TCP Protokoll. Mich würde jetzt 2 Dinge interessiere (später mehr).

    Wie kann ich den LoadBalancer für Worker Role(bei mehreren Instanzen) konfigugieren/implementieren? (ohne Queue?)

    Wann macht eigentlich eine Queue sinn? Ich meine, wenn ich weiß, dass nur max. 100 Anfrage pro Sekunde ankommt und jede Anfrage innerhalb von weniger Milisekunden beantwortet wird, dann bräuche ich hier keine Queue oder?

    Viele Grüße
    Nghia

    Donnerstag, 15. November 2012 12:39
  • Hi Nghia,

    vielen Dank :)

    Ich denke, die Konfiguration von Gladinet ist viel einfacher: der Endpunkt (also das, was Du in Gladinet unter "Account Name (Endpoint)", den Du brauchst, ist einfach der URL-Bestandteil, der vor blob.core.windows.net steht. In meinem Beispiel (siehe Abbildung hier) ist das also "hsirtl".

    Über den Button "Schlüsselverwaltung" bekommst Du Zugriff auf den Schlüssel, den Du in Gladinet als "Primary Access Key" angeben musst. Hier das Fenster der Schlüsselverwaltung:

    Für die Konfiguration von Gladinet brauchst Du also die beiden rot umrandeten Werte in obiger Abbildung).

    Einen Loadbalancer für WorkerRoles musst Du gar nicht implementieren. Der wird vollautomatisch von Azure konfiguriert, sobald für Deine Rollen einen Kommunikationsport in der *.csdef öffnest. Hier ein Beispiel:

    <?xml version="1.0" encoding="utf-8"?>

    <ServiceDefinition name="FTP2Azure" ...>

      <WorkerRole name="FTPServerRole">

        <Endpoints>

          <InputEndpoint name="FTP" port="21" protocol="tcp" />

          <InputEndpoint name="FTPPASV" protocol="tcp" port="59860" />

        </Endpoints>

        ...

      </WorkerRole>

    </ServiceDefinition>

    Das ist aus einem Blog, den ich diese Woche zum Thema "FTP-Zugriff auf Windows Azure Blob Storage" geschrieben habe. Dort werden für eine Worker Role zwei TCP-Ports geöffnet: Port 21 und Port 59860. Wenn jetzt mehrere Worker Roles gestartet werden, werden alle Zugriffe von außen zu einem der Ports automatisch auf die Worker Roles verteilt.

    Eine Queue macht dann Sinn, wenn Du Deine WorkerRole-Aufrufe asynchron durchführen möchtest bzw. kannst. Bei einem direkten WorkerRole-Aufruf wartest Du in Deinem Client ja in der Regel darauf, dass die Verarbeitung durch die WorkerRole abgeschlossen wird. Wenn das schnell geht (also beispielsweise eine Berechnung durchgeführt wird, auf deren Ergebnis Du wartest), ist das auch okay so (obwohl man Aufrufe ins Internet idealerweise immer asynchron implementieren sollte, damit der Client nicht blockiert wird, wenn bei der Netzverbindung etwas schief läuft). Wenn Du aber größere Arbeitsaufträge für die WorkerRoles hast (z.B. Video-Konvertierung), wäre es besser, Dein Client stellt einfach eine Nachricht mit einem Arbeitsauftrag in eine Queue. Dann kann Dein Client weiterarbeiten. Im Hintergrund liest dann eine verfügbare WorkerRole den Arbeitsauftrag aus und macht sich an die Verarbeitung. Dann stellt sich natürlich die Frage, wie Dein Client über den Abschluss der Verarbeitung bzw. das Ergebnis informiert wird. Ggf. kann der Client auch einfach immer wieder dort nachsehen wo WorkerRoles das Ergebnis hinschreiben (z.B. Blob Storage).

    In Deinem Fall brauchst Du bei den Annahmen, die Du oben schreibst, also nicht unbedingt eine Queue.

    Viele Grüße,

    Holger


    Holger Sirtl Senior Technical Evangelist, Microsoft Deutschland GmbH http://blogs.msdn.com/hsirtl


    Freitag, 16. November 2012 09:47
  • Also Holger, ich hoffe, ich habe es richtig verstanden
        <Endpoints>
    
          <InputEndpoint name="realPoint" port="19" protocol="tcp" />
    
          <InputEndpoint name="dummyPoint" protocol="tcp" port="20" />
    
        </Endpoints>

    Wenn ich also jetzt ein "dummyPoint" hinzufügen würde, dann würde die Last auf mehrere Instanzen verteilt ? (Selbst bei 4 Instanzen mit 2 Ports? Oder n-Ports für n- Instanzen?)

    Und die Clients sprechen nur den "realPoint" an und die Anfragen verteilt sich automatisch an die Instantzen?

            private IWorkerRole GetAProxy()
            {
    
                NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
                EndpointAddress endpointAddress
                    = new EndpointAddress("net.tcp://127.255.0.0:19/WCFTest");
    
                return new ChannelFactory<IWorkerRole>
                    (binding, endpointAddress).CreateChannel();
            }
    Stimmt meine Vorstellung soweit?

    Das Programm "Gladinet " funktioniert bei mir nicht, aber ich habe "CloudBerry Explorer for Azure Blob Storge" runtergeladen, ist zwar kein Virtuelle Laufwerk, funktioniert aber ganz gut. Ist einiges übersichtlicher und schneller als "Azure Storage Explorer".

    Viele Grüße und schöne Wochenende
    Nghia
    Freitag, 16. November 2012 13:43
  • Hallo Nghia,

    den "dummyPoint" brauchst du gar nicht. Im Grunde reicht ein Port (z.B. bei Dir Port 19). Wenn ein Client eine Anfrage auf diesem Port und der Adresse Deines Cloud Service (<servicename>.cloudapp.net) absetzt, dann kommt diese Anfrage erst mal noch nicht bei einer Instanz an sondern beim Loadbalancer. Der Loadbalancer verteilt nun alle eingehenden Nachrichten auf die Instanzen. Die jeweiligen Instanzen empfangen die Nachrichten also sozusagen vom Loadbalancer und zwar auf ihrem eigenen Port 19 (in jeder Instanz ist bei deiner Konfiguration oben Port 19 zum Empfang geöffnet). Optional könntest Du für Endpunkte auch interne Ports definieren, d.h. der Loadbalancer empfängt auf Port X, er leitet aber Anfragen an die Instanzen auf deren Port Y.

    Es ist also egal wie viele Instanzen gerade laufen, der Loadbalancer kennt sie alle und verteilt Anfragen an alle. Er passt sich auch dynamisch an Änderungen der Instanzen an. Das macht es auch möglich, zur Laufzeit Instanzen dazu zu schalten oder wegzunehmen ohne an der Port-Konfiguration was zu ändern. Das wird alles von Azure übernommen.

    Das Beispiel, das ich Dir oben geschickt hatte, hat zwei Ports geöffnet, weil für manche Aufrufe von den Clients der eine Port, für andere der andere Port verwendet wird.

    Ja, CloudBerry Explorer ist auch prima.

    Viele Grüße und ein schönes Wochenende,

    Holger


    Holger Sirtl Senior Technical Evangelist, Microsoft Deutschland GmbH http://blogs.msdn.com/hsirtl

    Freitag, 16. November 2012 14:38
  • Das ist ja großartig.

    Azure läuft, jetzt muss ich noch Storage-Blob, Service Bus, optional "Cache" testen, dann kann die richtige Implementierung beginnen.

    Vielen Dank für deine Unterstützung
    Nghia
    Freitag, 16. November 2012 15:49
  • Hallo Nghia,

    prima. Falls Du's noch nicht gesehen hast: für die Themen, die Du noch testen möchtest, schau Dir am besten das Windows Azure Training Kit an. Da findest Du viele sehr gute Tutorials, Beispiele und Hands-on-Labs für alle Bereiche von Windows Azure.

    Viele Grüße,

    Holger


    Holger Sirtl Senior Technical Evangelist, Microsoft Deutschland GmbH http://blogs.msdn.com/hsirtl

    Montag, 19. November 2012 08:55
  • Hallo Nghia,

    Hat Dir die Antwort von Holgen geholfen? Wenn ja - bitte markiere diese "als Antwort".

    Danke und Gruß,
    Ionut

    Montag, 19. November 2012 14:16
    Besitzer