In der vergangenen Woche habe ich mich in die Softwareentwicklung gewagt, indem ich das Konzept virtueller Akteure erforscht habe. Ich habe mich schließlich mit zwei verschiedenen Frameworks beschäftigt: Dapr und Orleans.
Beide sind sehr prägnante Projekte mit vielen interessanten Anwendungsfällen. Beide verwenden die Idee von "virtuellen" Schauspielern. Ein virtueller Akteur ist eine Zustands- und Logikeinheit, die:
- Sie kann eindeutig durch ID identifiziert werden
- Sie ist eingewindet
- Kann im Speicher oder persistent sein – sein Lebenszyklus wird vom Framework verwaltet
Mir gefällt die Idee der virtuellen Akteure sehr und ich finde sie sehr hilfreich bei meiner Erkundung, skalierbare und zuverlässige Werkzeuge für komplexe Aufgabenabläufe zu entwickeln. Wenn jede Aufgabe ein einsträngiger virtueller Teilnehmer ist, verschwindet das Rennbedingungsproblem.
Da Orleans und Dapr beide Microsoft-Projekte sind, stelle ich mir einen Tag in einem Western-Story-ähnlichen Duell in der Microsoft-Cafeteria vor.
Orleans
Ich habe mit Orleans angefangen, weil es schon eine Weile auf meinem Radar war, nachdem ich einige Videos dazu auf YouTube gesehen hatte. Es fing wirklich schlecht an, weil ich dachte, ich würde die 4.x-Version aller ihrer NuGet-Pakete verwenden. Allerdings funktioniert absolut keine ihrer Dokumentationen mit dem 4.x-Paket. Am Ende habe ich Version 3.6.2 verwendet.
Getreide / Zustand / Timer
Ein Korn zu erstellen, das seinen eigenen Zustand verfolgt und Aktionen ausführt, ist sehr einfach. Ich konnte sogar der Dokumentation zur Kornpersistenz folgen und meine eigene CosmosDB (SQL API) Implementierung von IGrainStorage erstellen.
Erinnerungen
Erinnerungen lassen sich ebenfalls leicht einstellen. Bis ich versucht habe, die reale Persistenz für sie zu konfigurieren. An diesem Punkt meiner Recherche versuche ich, alles ordentlich zu halten und alles in der ComsosDB zu lagern. Leider bekomme ich das Erinnerungs-Persistenzpaket von Orléans überhaupt nicht zum Laufen. Am Ende musste ich auf das AzureStorage-Paket umsteigen. Jetzt sind meine Daten also zur Hälfte im SQL-API-Konto und zur anderen Hälfte im Table-API-Konto.
Bäche
Da lief es nicht gut. In Orleans werden Flows durch einen GUID und einen optionalen Namensraum identifiziert. Ich bin sicher, es gibt einen guten Grund, warum Streams durch einen GUID identifiziert werden müssen, aber wow, das ist unpraktisch.
Ich bin sehr frustriert über Streams, weil ich sie einfach erstellen konnte, aber sobald ich mein Projekt stoppe, neu starte und ein neues Ereignis auslöse, stürzt alles ab.
Darauf folgt eine sehr wertvolle Information, da ich 8 Stunden gebraucht habe, um den Orleans-Code rückzuentwickeln, um das herauszufinden:
Wenn ein Grain ein Stream-Abonnent ist, muss das Grain ResumeAsync auf dem Abonnementhandle in seiner OnActivateAsync-Methode aufrufen, sonst stürzt der Fehler mit einem nicht erkannten Fehler ab.
Ich hatte auch das Problem, dass dasselbe Abonnement dupliziert wurde, also habe ich den Code verwendet, um alle Grain-Abonnements zu löschen und es dann neu erstellt:
Weitere Orleans-Fallen / Tipps
Streams funktioniert gut mit Azure Event Hubs (über AddEventHubStreams).
Verwende keine oder andere Sonderzeichen im Grain-Namen der CosmosDB SQL API!
Orleans-Fazit
Ich mag Orléans und denke, es hat Potenzial. Allerdings gibt es eine sehr steile Lernkurve. Aufgrund meines langen Problems mit dem Streaming habe ich keine Zeit, mich mit Clustern/Deployments zu beschäftigen.
Dapr
Ich habe Dapr gefunden, indem ich nach Alternativen zu Orléans gesucht habe. Es ist etwas seltsam, dass es auch ein von Microsoft gefördertes Projekt ist. Vielleicht sind sie hier, um den Überlebens-der-Stärker-Ansatz zu verfolgen. Wenn ja, denke ich, dass Dapr ein Überlebender sein wird.
Erstens erlaubt das REST/gRPC-basierte Design von Dapr, Akteure mit jeder Programmiersprache zu implementieren. Ich fand es auch trivial, alles (Teilnehmer, Status, Timer, Erinnerungen, Events) auf einer einzigen Redis-Instanz laufen zu lassen. Außerdem habe ich nur etwa ein Drittel der Zeit gebraucht, um mit Dapr anzufangen. Eine so schnelle Startzeit ist auf Daprs exzellente Dokumentation zurückzuführen.
Schauspieler / Timer / Erinnerungen
Habe ich gerade gesagt, dass Daprs Dokumentation großartig ist? Nun, es ist überall, außer bei JavaScript-Beispielen. Ich verbringe die meiste Zeit mit Dapr und versuche herauszufinden, wie man Methoden für Schauspieler anspricht. Der Code für das Dapr-Javascript-Beispiel lautet wie folgt:
Das ist eindeutig veraltet. Ich musste viel Zeit darauf verwenden, diese drei Zeilen durch Daprs Test- und Beispielcode-Exploration zu überreden
Die Codebeispiele zum Erfassen/Setzen des Zustands haben ähnliche Probleme, also habe ich ein GitHub-Problem für sie erstellt.
Abgesehen von diesen kleinen Problemen ist es ein Kinderspiel, Schauspieler einzurichten.
Das Setzen von Timern und Erinnerungen für meinen Cast ist ebenfalls sehr einfach.
Zustand
Ich konnte Dapr sehr einfach so konfigurieren, dass es mit Postgres aufrechterhalten bleibt.
Eine Sache, die mir aufgefallen ist, ist, dass es Skalierbarkeitsprobleme bei der Speicherung von Erinnerungen geben könnte. Dapr speichert alle Benachrichtigungen für einen bestimmten Teilnehmertyp in einem einzigen JSON-Array. Was passiert, wenn jemand eine Menge Erinnerungen hat?
Weitere Dapr-Fallen / Tipps
Eine Sache, die mir beim Durchstöbern des JavaScript-SDK-Codes aufgefallen ist, ist, dass es in der Codebasis kaum Kommentare gibt. Das macht es fast unmöglich, etwas herauszufinden. Zum Beispiel gibt es in der addOrUpdateState-Methode des State Managers einen dritten Parameter namens updateValueFactory. Wenn es keine Kommentare im Code gibt, ist es fast unmöglich zu erkennen, wofür der Rückruf gedacht ist.
Ich bin mir auch nicht sicher, wie sehr mir der Befehl "dapr init" gefällt, wenn ich versuche, einen Redis-Container für mich einzurichten und auszuführen. Was, wenn ich bereits einen Redis-Behälter habe? Was, wenn ich stattdessen Postgres verwenden möchte? Ich finde keine Dokumentation, die erklärt, wie man die DAPR-Init-Funktion ändert.
Ein Hinweis an alle, die Schwierigkeiten haben, pubsub zu nutzen. Sie müssen "dapr run" verwenden, um sowohl Ihren Verlag als auch Ihren Abonnenten zu betreiben:
Für Actors und Pubsub ist es wichtig, den Parameter --app-port zu verwenden, um DAPR mitzuteilen, auf welchem Port dein Dienst läuft. Pubsub-Events und Actor-Calls werden vom Dapr-Sidecar über http-Calls an Ihren Service gesendet, daher muss er wissen, wohin er sie senden soll:
Ich habe einen kleinen selbstgehosteten Dapr-"Cluster" getestet, indem ich meine PubSub-Abonnenteninstanz auf zwei verschiedenen Rechnern in meinem Heimnetzwerk gestartet habe. Es hat einfach funktioniert!
Dapr-Schlussfolgerung
Wenn Sie mehr Ideen zu verteilten Anwendungen oder virtuellen Akteuren erfahren möchten, empfehle ich Ihnen, mit Dapr zu beginnen. Orleans war der ursprüngliche Wegbereiter, während Dapr ein Reboot war, der die Dinge auf die nächste Stufe gehoben hat.
Originallink:Der Hyperlink-Login ist sichtbar.
|