Heimtückische Queues bei Windows Azure (EDT 08/30/10)
Muss mal wieder was zur Erkenntnis des Tages schreiben, sonst glaubt mir keiner mehr, dass das eine kleine Serie ist. Meine aktuelle Erkenntnis stützt sich auf meine Erfahrungen von gestern, nachdem ich das Ameisenspiel AntMe! (www.antme.net) für die Cloud startklar gemacht habe. Spieler werden in Zukunft die Chance haben, ihre programmierten Ameisen direkt zum Online-Portal hochzuladen und dann andere Spieler herauszufordern. Die Simulation muss dann natürlich auf dem Server stattfinden. Um da ordentlich zu skalieren, gehen wir natürlich gleich in die Cloud.
Für einen ordentlichen Datenaustausch bietet Azure neben SQL Azure auch Windows Azure eigene Speichermedien. Da gibt es die Tabellen, die garkeine richtigen Tabellen sind. Dann hat es noch Queues zur Kommunikation zwischen den einzelnen parallelen Prozessen und am Ende noch Blobs, um die wirklich fetten Daten abzulegen.
Wie funktionierts? Neben der eigentlichen Webseite, deren Datenbank direkt bei SQL Azure liegt, existieren 2 Worker Roles in Azure. Eine davon übernimmt die Rolle des Queue-Managers. Sie liest aus SQL Azure aus, welche Simulationen durchgeführt werden müssen, bereitet die Daten für die Simulations-Rollen korrekt auf (Daten werden dann in den Tabellen gehalten) und ein Simulationsauftrag wird in eine Queue geschoben. Simulatoren sind auch Worker Roles und können in x-facher Instanz laufen. Eine dieser Simulatoren holt sich einen Auftrag aus der Queue, grabscht sich die zusätzlichen Daten aus den Tabellen und beginnt die Simulation. Die Aufzeichnung der Simulation wird direkt als Stream in einen neuen Blob gestreamt, wo der spieler es später direkt per URL zur Wiedergabe heraus streamen kann.
Aber nun zu meiner Erkenntnis: Implementierung dieser Interprozess-Kommunikation ist denkbar einfach. Tabellen-Entitäten werden im Stil des Entity Frameworks erstellt und bei Start der Rolle mit einem simplen “Erstell-wenn-noch-nicht-vorhanden”-Befehl im Table-Storage angelegt. Danach greift man über einen zentralen Datacontext darauf zu. Wow! Noch einfacher ist es mit den Queues und Blobs. Dort ist mit 2 Zeilen Code eine Verbindung zu vorhandenen (oder bei Bedarf neu erstellten) Datenquelle hergestellt und es kann los gehen. Queues werden wahlweise mit Strings oder Byte-Arrays gefüttert und Blogs per Stream gefüttert. Denkbarst einfach! Danke Azure. Innerhalb von einer Stunde hatte ich eine funktionierende Lösung.
Worauf ich aber eigentlich raus wollte:
Wenn ihr Queues verwendet, dann achtet bitte darauf, dass ihr entnommene Messages auch aus der Queue löscht. Sehr eigenartiges Konzept. Messages bleiben bei einem Pop in der Queue, sind aber für knapp 30 Sekunden nicht sichtbar. Nach einem Pop muss die Message also nochmal explizit aus der Queue gelöscht werden, damit der Service nicht endlos die selbe Message bearbeitet.