Azure Storage Queue - korreliert die Antwort auf die Anforderung

8

Wie kann eine Webrolle eine Nachricht in eine Speicherwarteschlange stellen, wie kann sie nach einer bestimmten korrelierten Antwort suchen? Ich möchte, dass die Back-End-Worker-Rolle eine Nachricht in eine Antwortwarteschlange legt, mit der Absicht, dass der Anrufer die Antwort auswählen und von dort aus gehen würde.

Unsere Absicht ist es, die Warteschlange zu nutzen, um eine starke Verarbeitung in die Back-End-Worker-Rollen auszulagern, um eine hohe Leistung in den Webrollen sicherzustellen. Wir möchten jedoch nicht auf die HTTP-Anforderungen antworten, bis die Back-End-Workers fertig sind und geantwortet haben.

    
Pittsburgh DBA 16.02.2012, 21:20
quelle

6 Antworten

4

Ich bin gerade dabei, eine ähnliche Entscheidung zu treffen. In meinem Fall habe ich einen WCF-Dienst, der in einer Webrolle ausgeführt wird, die Berechnungen zu Worker-Rollen auslasten sollte. Wenn das Ergebnis berechnet wurde, gibt die Webrolle die Antwort an den Client zurück.

Mein grundlegendes Datenstrukturwissen sagt mir, dass ich es vermeiden sollte, etwas zu verwenden, das als Warteschlange in einer nichtwarteschlangenartigen Weise ausgelegt ist. Das bedeutet, dass eine Warteschlange immer in einer FIFO-ähnlichen Weise bedient werden sollte. Wenn also Warteschlangen sowohl für Anforderungen als auch für Antwort verwendet werden, müssen die Threads, die darauf warten, Daten an den Client zurückzugeben, warten, bis sich die Berechnungsnachricht an der "Spitze" der Antwortwarteschlange befindet, was nicht optimal ist. Wenn die Antworten mithilfe von Azure-Tabellen gespeichert werden, werden von den Threads Nachrichten abgefragt, die unnötigen Aufwand verursachen.

Was ich glaube, ist eine mögliche Lösung für dieses Problem ist die Verwendung einer Warteschlange für die Anfragen. Dies ermöglicht die Verwendung des konkurrierenden Verbrauchermusters und dadurch Lastausgleich. Bei Nachrichten, die in diese Warteschlange gesendet werden, legen Sie die Eigenschaft correlationId fest die Nachricht. Zur Antwort wird der Teil des Azure-Servicebusses für den Pub / Sub-Teil ("Themen") zusammen mit einem Korrelationsfilter . Wenn Ihr Back-End die Anfrage bearbeitet hat, hat es ein Ergebnis an ein "responseSubject" mit der correlationId in der ursprünglichen Anfrage veröffentlicht. Nun kann diese Antwort von Ihrem Client durch Aufrufen von CreateSubscribtion (Sorry, ich kann nicht mehr als zwei Links scheinbar poste, google es) mit diesem Korrelationsfilter abgerufen werden, und es sollte benachrichtigt werden, wenn die Antwort veröffentlicht wird. Beachten Sie, dass der CreateSubscribtion-Teil in der OnStart-Methode nur einmal ausgeführt werden sollte. Dann können Sie eine asynchrone BeginRecieve für diese Subskription ausführen, und die Rolle wird im angegebenen Callback benachrichtigt, wenn eine Antwort für eine ihrer Anforderungen verfügbar ist. Die correlationId wird Ihnen sagen, für welche Anfrage die Antwort ist. Ihre letzte Herausforderung besteht darin, diese Antwort an den Thread zurückzugeben, der die Clientverbindung hält.

Dies kann erreicht werden, indem ein Dictionary mit den Korrelations-IDs (wahrscheinlich GUIDs) als Schlüssel und Antworten als Wert erstellt wird. Wenn Ihre Webrolle eine Anforderung erhält, erstellt sie die GUID, legt sie als correlationId fest, fügt ihr das hashset hinzu, löst die Nachricht in der Warteschlange aus und ruft dann Monitor.Wait () für das Guid-Objekt auf. Dann muss die recieve-Methode, die von der Themen-Subskription aufgerufen wird, die Antwort dem Dictionary hinzufügen und dann Monitor.Notify () für dasselbe GUID-Objekt aufrufen. Dies weckt Ihren ursprünglichen Request-Thread und Sie können nun die Antwort an Ihren Client zurückgeben (Oder etwas. Im Grunde wollen Sie nur, dass Ihr Thread schläft und keine Ressourcen verbraucht, während Sie warten)

    
Henrikmh 19.02.2012, 22:23
quelle
3

Die Warteschlangen auf dem Azure Service Bus verfügen über wesentlich mehr Funktionen und Paradigmen, einschließlich pub / sub -Funktionen, die Probleme bei der Warteschlangenwartung über mehrere Instanzen hinweg beheben können.

Ein Ansatz mit pub / sub besteht darin, eine Warteschlange für Anfragen und eine für die Antworten zu haben. Jede anfragende Instanz würde auch die Antwortwarteschlange mit einem Filter für den Header abonnieren, so dass sie nur die für sie bestimmten Antworten erhalten würde. Die Anforderungsnachricht würde natürlich den Wert enthalten, der in dem Antwortheader platziert wird, um den Filter zu steuern.

    
hocho 17.02.2012 05:18
quelle
3

Für die Service-Bus-basierte Lösung gibt es Beispiele für die Implementierung von Request / Response-Mustern mit Warteschlangen und Themen (pub-sub)

    
Abhishek Lal 17.02.2012 18:24
quelle
2

Lassen Sie die Mitarbeiterrolle die Abfrage fortsetzen und die Nachricht verarbeiten. Sobald die Nachricht verarbeitet wurde, fügen Sie einen Eintrag im Tabellenspeicher mit der erforderlichen corelationId (RowKey) und dem Verarbeitungsergebnis hinzu, bevor Sie die verarbeitete Nachricht aus der Warteschlange löschen.

Dann müssen WebRoles nur einen Blick auf die Tabelle mit der gewünschten correlationId (RowKey) & amp; PartitionKey

    
Jash 16.02.2012 22:22
quelle
2

Sehen Sie sich SignalR zwischen der Worker-Rolle und dem Browser-Client an. Ihre Webrolle fügt also eine Nachricht in die Warteschlange ein und gibt ein Ergebnis an den Browser zurück (etwas einfaches wie "Warten ...") und hakt es mit Signal an die Worker-Rolle. Auf diese Weise macht Ihre Webrolle andere Aufgaben und muss nicht auf ein Ergebnis der asynchronen Verarbeitung warten, das muss nur der Browser tun.

    
Simon Munro 17.02.2012 10:51
quelle
1

Windows Azure-Warteschlangen haben nichts mit dem zu tun, was Sie fragen. Sie können dies jedoch relativ einfach selbst aufbauen. Fügen Sie eine Nachrichten-ID (GUID) in Ihre Push-Nachricht zur Warteschlange ein. Wenn die Verarbeitung abgeschlossen ist, lassen Sie den Mitarbeiter eine neue Nachricht mit dieser Nachrichten-ID in eine Antwortkanalwarteschlange senden. Ihre Webanwendung kann diese Warteschlange abfragen, um festzustellen, wann die Verarbeitung für einen bestimmten Befehl abgeschlossen ist.

Wir haben etwas Ähnliches getan und versuchen, etwas wie SignalR zu verwenden, um dem Client zu antworten, wenn die Befehle abgeschlossen sind.

    
dunnry 16.02.2012 21:40
quelle