V zadnjem tednu sem se podal v razvoj programske opreme z raziskovanjem koncepta virtualnih akterjev. Na koncu sem si ogledal dva različna ogrodja: Dapr in Orleans.
Oba projekta sta zelo jedrnata z veliko zanimivimi primeri uporabe. Oba uporabljata idejo "virtualnih" akterjev. Virtualni igralec je enota stanja in logike, ki:
- Lahko ga enolično identificiramo z ID-jem
- Je enonitna
- Lahko je v pomnilniku ali trajna – njen življenjski cikel upravlja okvir
Zelo mi je všeč ideja virtualnih akterjev in mi zelo pomagajo pri raziskovanju gradnje razširljivih in zanesljivih orodij za obvladovanje zahtevnih delovnih tokov. Če je vsaka naloga enonitni virtualni udeleženec, problem tekmovalnih pogojev izgine.
Ker sta Orleans in Dapr oba Microsoftova projekta, si predstavljam dan v slogu Western Story obračuna v Microsoftovi menzi.
Orleans
Začel sem z Orleansom, ker je že nekaj časa na mojem radarju, potem ko sem videl nekaj videov o njem na YouTubu. Začelo se je zelo slabo, ker sem mislil, da bom uporabljal 4.x različico vseh njihovih NuGet paketov. Vendar pa nobena njihova dokumentacija ne deluje z 4.x paketom. Na koncu sem uporabil različico 3.6.2.
Žita / Država / Časovniki
Ustvarjanje zrna, ki sledi svojemu stanju in izvaja dejanja, je zelo preprosto. Uspešno sem sledil dokumentaciji za obstojnost zrn in ustvaril svojo lastno implementacijo CosmosDB (SQL API) za IGrainStorage.
Opomnike
Opomnike je prav tako enostavno nastaviti. Dokler nisem poskušal nastaviti resnične trajnosti za njih. Trenutno v svojem raziskovanju poskušam vse ohranjati urejeno in shranjevati v ComsosDB. Na žalost mi Orleansov paket za opomnike za vztrajnost sploh ne deluje v delovanju. Na koncu sem moral preiti na paket AzureStorage. Zdaj so moji podatki pol v SQL API računu in polovica v tabeli API računu.
Tokov
Tam mi ni šlo dobro. V Orleansu so tokovi identificirani z GUID in opcijskim imenskim prostorom. Prepričan sem, da obstaja dober razlog, zakaj morajo biti tokovi označeni z GUID-jem, ampak to je nepraktično.
Zelo sem frustriran nad tokovi, ker sem jih lahko enostavno ustvaril, a ko ustavim in ponovno zaženem projekt ter sprožim nov dogodek, se vse sesuje.
Sledi zelo dragocena informacija, saj sem potreboval 8 ur, da sem razvozlal Orleansovo kodo in jo razvozlal:
Ko je zrno naročnik toka, mora zrno poklicati ResumeAsync na naročniškem ročaju v svoji metodi OnActivateAsync, sicer se bo zrušilo z neprepoznano napako.
Imel sem tudi težavo, da je bila ista naročnina podvojena, zato sem s kodo izbrisal vse naročnine žita in jo nato ponovno ustvaril:
Drugi Orleansovi triki / nasveti
Streams dobro deluje z Azure Event Hubs (prek AddEventHubStreams).
Ne uporabljajte / ali drugih posebnih znakov v imenu Grain v CosmosDB SQL API!
Orleanski zaključek
Všeč mi je Orleans in mislim, da ima potencial. Vendar pa ima zelo strmo učno krivuljo. Zaradi dolgotrajnih težav s pretakanjem nimam časa preučevati, kako delujejo grozdi/namestitve.
Dapr
Dapr sem našel tako, da sem iskal alternative Orleansu. Malce nenavadno je, da je to tudi Microsoftov projekt. Morda so tukaj zato, da sprejmejo pristop preživetja najmočnejših. Če da, mislim, da bo Dapr preživel.
Prvič, Daprjeva zasnova, ki temelji na REST/gRPC, omogoča implementacijo akterjev v katerem koli programskem jeziku. Prav tako se mi je zdelo trivialno zagnati vse (udeležence, statuse, časovnike, opomnike, dogodke) na eni sami Redis instanci. Poleg tega sem začel uporabljati Dapr v približno tretjini časa. Tako hiter zagon je posledica odlične dokumentacije podjetja Dapr.
Igralci / Časovniki / Opomniki
Sem pravkar rekel, da je dokumentacija Dapr odlična? No, povsod je, razen v primerih JavaScripta. Večino časa preživim na Dapru, kjer poskušam ugotoviti, kako klicati metode na igralcih. Koda za Dapr Javascript vzorec je naslednja:
To je očitno zastarelo. Veliko časa sem moral porabiti za prepričevanje teh treh vrstic skozi Daprjevo testno/vzorčno raziskovanje kode
Primeri kode za pridobivanje in nastavitev stanja imajo podobne težave, zato sem zanje ustvaril GitHub težavo.
Razen teh manjših težav je postavitev igralcev mačji kašelj.
Nastavitev časovnikov in opomnikov za mojo zasedbo je prav tako zelo enostavna.
Država
Dapr sem lahko zelo enostavno nastavil tako, da je vztrajal s Postgresom.
Ena stvar, ki sem jo opazil, je, da so lahko težave z razširljivostjo pri shranjevanju opomnikov. Dapr shranjuje vsa opozorila za določen tip udeleženca v eno samo JSON matriko. Kaj se zgodi, če ima nekdo ogromno opomnikov?
Drugi Dapr triki / nasveti
Ena stvar, ki sem jo opazil med brskanjem po kodi za JavaScript SDK, je, da v kodi sploh ni veliko komentarjev. Zaradi tega je skoraj nemogoče kaj ugotoviti. Na primer, v metodi addOrUpdateState upravitelja stanja obstaja tretji parameter, imenovan updateValueFactory. Če v kodi ni komentarjev, je skoraj nemogoče ugotoviti, za kaj je povratni klic.
Prav tako nisem prepričan, koliko mi je všeč ukaz "dapr init", ki poskuša nastaviti in zagnati redis kontejner zame. Kaj pa, če že imam redisovo posodo? Kaj pa, če raje uporabim postgres? Ne najdem dokumentacije, ki bi razlagala, kako spremeniti funkcijo dapr init.
Opomba za vse, ki imajo težave z uporabo pubsuba. Uporabiti morate "dapr run" za delovanje tako založnika kot naročnika:
Za igralce in pubsub je pomembno, da uporabite parameter --app-port, da dapr ve, na katerem portu teče vaša storitev. pubsub dogodki in klici igralcev se pošiljajo vaši storitvi iz Dapr sidecarja preko HTTP klicev, zato mora vedeti, kam jih poslati:
Testiral sem majhen Dapr samostojno gostovan "grozd" tako, da sem zagnal svojo pubsub naročniško instanco na dveh različnih računalnikih v mojem domačem omrežju. Preprosto je delovalo!
Zaključek Dapr
Če želite izvedeti več o porazdeljenih aplikacijah ali virtualnih akterjih, priporočam, da začnete z Dapr. Orleans je bil prvotni pionir, medtem ko je bil Dapr ponovni zagon, ki je stvari popeljal na višjo raven.
Izvirna povezava:Prijava do hiperpovezave je vidna.
|