De afgelopen week ben ik me aan softwareontwikkeling begonnen door het concept van virtuele actoren te onderzoeken. Uiteindelijk ben ik naar twee verschillende frameworks gegaan: Dapr en Orleans.
Beide zijn zeer beknopte projecten met veel interessante gebruiksscenario's. Beide gebruiken het idee van "virtuele" actors. Een virtuele actor is een toestands- en logische eenheid die:
- Het kan uniek worden geïdentificeerd door ID
- Hij is enkeldraads
- Kan in het geheugen of persistent zijn - de levenscyclus wordt beheerd door het framework
Ik vind het idee van virtuele actors erg leuk en vind ze erg nuttig bij mijn verkenning van het bouwen van schaalbare en betrouwbare tools om complexe taakprocessen aan te kunnen. Als elke taak een single-threaded virtuele deelnemer is, verdwijnt het raceconditieprobleem.
Omdat Orleans en Dapr beide Microsoft-projecten zijn, zie ik een dag voor me in een Western Story-achtige confrontatie in de Microsoft-kantine.
Orleans
Ik ben begonnen met Orleans omdat het al een tijd op mijn radar stond na het zien van wat video's erover op YouTube. Het begon echt slecht omdat ik dacht dat ik de 4.x-versie van al hun NuGet-pakketten zou gebruiken. Echter, absoluut geen van hun documentatie werkt met het 4.x-pakket. Uiteindelijk heb ik versie 3.6.2 gebruikt.
Graan / Toestand / Timers
Het creëren van een korrel die zijn eigen toestand bijhoudt en acties uitvoert is heel eenvoudig. Ik kon zelfs de documentatie voor grainpersistence volgen en mijn eigen CosmosDB (SQL API) implementatie van IGrainStorage maken.
Herinneringen
Herinneringen zijn ook eenvoudig in te stellen. Totdat ik probeerde de persistentie in de echte wereld voor ze te configureren. Op dit punt in mijn onderzoek probeer ik alles netjes te houden en alles op te slaan in ComsosDB. Helaas krijg ik het herinnerings-persistentiepakket van Orléans helemaal niet werkend. Uiteindelijk moest ik overstappen op het AzureStorage-pakket. Dus nu zit mijn data voor de helft in het SQL API-account en voor de helft in het table API-account.
Streams
Daar ging het niet goed. In Orleans worden stromen geïdentificeerd door een GUID en een optionele naamruimte. Ik weet zeker dat er een goede reden is waarom streams door een GUID geïdentificeerd moeten worden, maar wow, dat is onpraktisch.
Ik ben erg gefrustreerd door streams omdat ik ze makkelijk kon aanmaken, maar zodra ik stop en mijn project opnieuw start en een nieuw event activeer, crasht alles.
Hierop volgt een zeer waardevol stukje informatie, want het kostte me 8 uur om de Orleans-code te reverse-engineeren om het uit te zoeken:
Wanneer een grain een streamabonnee is, moet de grain ResumeAsync aanroepen op de abonnementshandle in zijn OnActivateAsync-methode, anders crasht u met een onherkende foutmelding.
Ik had ook het probleem dat hetzelfde abonnement werd gedupliceerd, dus gebruikte ik de code om alle grain-abonnementen te verwijderen en maakte het daarna opnieuw aan:
Andere valkuilen in Orleans / tips
Streams werkt goed met Azure Event Hubs (via AddEventHubStreams).
Gebruik geen / of andere speciale tekens in de Grain-naam van de CosmosDB SQL API!
Orleans-conclusie
Ik vind Orléans leuk en ik denk dat het potentie heeft. Het heeft echter een zeer steile leercurve. Door mijn lange worsteling met streamen heb ik geen tijd om te onderzoeken hoe clusters/deployments werken.
Dapr
Ik vond Dapr door te zoeken naar alternatieven voor Orléans. Het is een beetje vreemd dat het ook een door Microsoft gesponsord project is. Misschien zijn ze hier om een survival of the fittest-aanpak te hanteren. Als dat zo is, denk ik dat Dapr een overlever zal zijn.
Ten eerste maakt het REST/gRPC-gebaseerde ontwerp van Dapr het mogelijk om actors te implementeren met elke programmeertaal. Ik vond het ook eenvoudig om alles (deelnemers, statussen, timers, herinneringen, evenementen) op één enkele Redis-instantie te draaien. Daarbovenop duurde het maar ongeveer een derde van de tijd voordat ik begon met Dapr. Zo'n snelle opstarttijd is te danken aan de uitstekende documentatie van Dapr.
Acteurs / Timers / Herinneringen
Heb ik net gezegd dat de documentatie van Dapr geweldig is? Nou, het is overal, behalve bij JavaScript-voorbeelden. Ik breng het grootste deel van mijn tijd door met Dapr, terwijl ik probeer uit te zoeken hoe ik methoden op acteurs kan aanspreken. De code voor het Dapr Javascript-voorbeeld is als volgt:
Dit is duidelijk verouderd. Ik moest veel tijd besteden aan het overhalen van deze drie regels via Dapr's test-/voorbeeldcode-verkenning
De codevoorbeelden voor het krijgen/instellen van status hebben vergelijkbare problemen, dus heb ik een GitHub-issue voor hen gemaakt.
Behalve die kleine problemen is het opzetten van acteurs een fluitje van een cent.
Het instellen van timers en herinneringen voor mijn cast is ook heel eenvoudig.
Staat
Ik kon Dapr heel gemakkelijk configureren om met Postgres te blijven werken.
Wat me is opgevallen, is dat er mogelijk schaalbaarheidsproblemen zijn met hoe herinneringen worden opgeslagen. Dapr slaat alle meldingen voor een specifiek type deelnemer op in één enkele JSON-array. Wat gebeurt er als iemand een hoop herinneringen heeft?
Andere Dapr-valkuilen / tips
Wat me opviel bij het bladeren in de code van de JavaScript SDK is dat er helemaal niet veel reacties in de codebase staan. Dit maakt het bijna onmogelijk om iets te achterhalen. Bijvoorbeeld, in de addOrUpdateState-methode van de state manager is er een derde parameter genaamd updateValueFactory. Als er geen opmerkingen in de code staan, is het bijna onmogelijk om te zien waar de terugbelactie voor is.
Ik weet ook niet zeker hoeveel ik het commando "dapr init" vind als ik probeer een redis-container voor mij op te zetten en te draaien. Wat als ik al een redis-container heb? Wat als ik in plaats daarvan Postgres wil gebruiken? Ik kan geen documentatie vinden die uitlegt hoe je de DAPR Init-functie kunt wijzigen.
Een opmerking voor iedereen die moeite heeft met het gebruik van pubsub. Je moet "dapr run" gebruiken om zowel je uitgever als je abonnee te runnen:
Voor actors en pubsub is het belangrijk om de parameter --app-port te gebruiken om DAPR te laten weten op welke poort je dienst draait. pubsub-evenementen en actor-oproepen worden via http-calls naar je dienst gestuurd vanuit de Dapr-sidecar, dus het moet weten waar ze naartoe moeten:
Ik heb een kleine Dapr zelfgehoste "cluster" getest door mijn pubsub-abonnee-instantie op twee verschillende machines op mijn thuisnetwerk te starten. Het werkte gewoon!
Conclusie over Dapr
Als je meer ideeën wilt weten over gedistribueerde applicaties of virtuele actors, raad ik je aan te beginnen met Dapr. Orléans was de oorspronkelijke pionier, terwijl Dapr een reboot was die het naar een hoger niveau tilde.
Originele link:De hyperlink-login is zichtbaar.
|