Under den senaste veckan har jag gett mig in i mjukvaruutveckling genom att forska om konceptet virtuella aktörer. Jag slutade med att titta på två olika ramverk: Dapr och Orleans.
Båda är mycket koncisa projekt med massor av intressanta användningsområden. Båda använder idén om "virtuella" aktörer. En virtuell aktör är en tillstånds- och logikenhet som:
- Den kan entydigt identifieras genom ID
- Den är enkeltrådad
- Kan vara i minnet eller persistent – dess livscykel hanteras av ramverket
Jag gillar verkligen idén med virtuella aktörer och tycker de är mycket hjälpsamma i min utforskning av att bygga skalbara och pålitliga verktyg för att hantera komplexa arbetsflöden. Om varje uppgift är en enkeltrådad virtuell deltagare försvinner problemet med racevillkoret.
Eftersom Orleans och Dapr båda är Microsoft-projekt föreställer jag mig en dag i en Western Story-liknande uppgörelse i Microsofts matsal.
Orleans
Jag började med Orleans eftersom det har varit på min radar ett tag efter att ha sett några videor om det på YouTube. Det började riktigt dåligt eftersom jag trodde att jag skulle använda 4.x-versionen av alla deras NuGet-paket. Men absolut ingen av deras dokumentation fungerar med 4.x-paketet. Jag slutade med att använda version 3.6.2.
Spannmål / Tillstånd / Timers
Att skapa ett korn som spårar sitt eget tillstånd och utför handlingar är mycket enkelt. Jag kunde till och med följa dokumentationen för grainpersistens och skapa min egen CosmosDB (SQL API)-implementation av IGrainStorage.
Påminnelser
Påminnelser är också lätta att ställa. Tills jag försökte konfigurera verklig persistens för dem. Just nu försöker jag hålla allt prydligt och lagra allt i ComsosDB. Tyvärr kan jag inte få Orléans påminnelse-persistenspaket att fungera alls. Jag var tvungen att byta till AzureStorage-paketet. Så nu är min data hälften i SQL API-kontot och hälften i tabell-API-kontot.
Strömmar
Det var där det inte gick bra för mig. I Orleans identifieras flöden av en GUID och ett valfritt namnrymd. Jag är säker på att det finns en bra anledning till att strömmar måste identifieras av en GUID, men wow, det är opraktiskt.
Jag är väldigt frustrerad över streams eftersom jag kunde skapa dem enkelt, men när jag stoppar och startar om mitt projekt och triggar en ny händelse kraschar allt.
Detta följs av en mycket värdefull information, eftersom det tog mig 8 timmar att bakåtkonstruera Orleans-koden för att lista ut det:
När ett grain är en strömprenumerant måste grainet anropa ResumeAsync på prenumerationshandtaget i sin OnActivateAsync-metod, annars kraschar du med ett oigenkänd fel.
Jag hade också problemet att samma prenumeration var duplicerad, så jag använde koden för att ta bort alla grains prenumerationer och skapade sedan om den:
Andra Orleans-fällor / tips
Streams fungerar bra med Azure Event Hubs (via AddEventHubStreams).
Använd inte / eller andra specialtecken i Grain-namnet på CosmosDB SQL API:Tet!
Orléans-slutsats
Jag gillar Orléans och jag tycker att det har potential. Men det har en mycket brant inlärningskurva. På grund av min långa kamp med streaming har jag inte tid att studera hur kluster/utrullningar fungerar.
Dapr
Jag hittade Dapr genom att leta efter alternativ till Orléans. Det är lite märkligt att det också är ett Microsoft-sponsrat projekt. Kanske är de här för att ta en överlevnadsstrategi av den starkeste. Om ja, tror jag att Dapr kommer att vara en överlevare.
För det första tillåter Daprs REST/gRPC-baserade design att aktörer kan implementeras med vilket programmeringsspråk som helst. Jag tyckte också det var enkelt att köra allt (deltagare, statusar, timers, påminnelser, händelser) på en enda Redis-instans. Dessutom tog det mig bara ungefär en tredjedel av tiden att börja använda Dapr. Den så snabba starttiden beror på Daprs utmärkta dokumentation.
Skådespelare / Timers / Påminnelser
Sa jag just att Daprs dokumentation är fantastisk? Tja, det finns överallt, förutom JavaScript-exempel. Jag tillbringar mesta delen av min tid på Dapr, försöker lista ut hur man kallar metoder på skådespelare. Koden för Dapr Javascript-exemplet är följande:
Detta är uppenbarligen föråldrat. Jag var tvungen att lägga mycket tid på att locka dessa tre rader genom Daprs test-/exempelkodsutforskning
Kodexemplen för att få/sätta tillstånd har liknande problem, så jag skapade ett GitHub-problem för dem.
Bortsett från de där små problemen är det enkelt att sätta upp skådespelare.
Att ställa in timers och påminnelser för min cast är också väldigt enkelt.
Stat
Jag kunde konfigurera Dapr att fortsätta med Postgres väldigt enkelt.
En sak jag har märkt är att det kan finnas skalbarhetsproblem med hur påminnelser lagras. Dapr lagrar alla aviseringar för en specifik deltagartyp i en enda JSON-array. Vad händer om någon har massor av påminnelser?
Andra Dapr-fällor / tips
En sak jag märkte när jag bläddrade i koden för JavaScript-SDK:n är att det inte finns många kommentarer i kodbasen alls. Det gör det nästan omöjligt att lista ut något. Till exempel, i state managers addOrUpdateState-metod finns en tredje parameter som kallas updateValueFactory. Om det inte finns några kommentarer i koden är det nästan omöjligt att avgöra vad återkallelsen är till för.
Jag är inte heller säker på hur mycket jag gillar kommandot "dapr init" när jag försöker sätta upp och köra en redis-container åt mig. Vad händer om jag redan har en redis-behållare? Vad händer om jag vill använda Postgres istället? Jag kan inte hitta någon dokumentation som förklarar hur man ändrar DAPR init-funktionen.
En notis till alla som har problem med att använda pubsub. Du måste använda "dapr run" för att driva både din utgivare och prenumerant:
För aktörer och pubsub, observera att det är viktigt att använda parametern --app-port för att låta DAPR veta vilken port din tjänst körs på. pubsub-händelser och actor-anrop skickas till din tjänst från Dapr-sidovagnen via http-samtal, så den behöver veta vart de ska skickas:
Jag testade ett litet Dapr-självhostat "kluster" genom att starta min pubsub-prenumerationsinstans på två olika maskiner i mitt hemnätverk. Det bara fungerade!
Dapr-slutsats
Om du vill veta mer om distribuerade applikationer eller virtuella aktörer rekommenderar jag att du börjar med Dapr. Orléans var den ursprungliga pionjären, medan Dapr var en reboot som tog saker till nästa nivå.
Originallänk:Inloggningen med hyperlänken är synlig.
|