Nell'ultima settimana, mi sono avventurato nello sviluppo software studiando il concetto di attori virtuali. Alla fine ho cercato due framework diversi: Dapr e Orleans.
Entrambi sono progetti molto concisi con tantissimi casi d'uso interessanti. Entrambi utilizzano l'idea di attori "virtuali". Un attore virtuale è un'unità di stato e logica che:
- Può essere identificata in modo unico tramite ID
- È a filettatura singola
- Può essere in memoria o persistente - il suo ciclo di vita è gestito dal framework
Mi piace molto l'idea degli attori virtuali e li trovo molto utili nella mia esplorazione della creazione di strumenti scalabili e affidabili per gestire flussi di lavoro complessi. Se ogni task è un partecipante virtuale a thread singolo, il problema della condizione di gara scompare.
Poiché Orleans e Dapr sono entrambi progetti Microsoft, immagino una giornata in uno scontro in stile Western Story alla mensa Microsoft.
Orleans
Ho iniziato con Orleans perché è stato nel mio radar da un po' di tempo dopo aver visto alcuni video su YouTube. È iniziato davvero male perché pensavo di usare la versione 4.x di tutti i loro pacchetti NuGet. Tuttavia, assolutamente nessuna delle loro documentazioni funziona con il pacchetto 4.x. Alla fine ho usato la versione 3.6.2.
Cereali / Stato / Timers
Creare un grano che traccia il proprio stato ed esegue azioni è molto semplice. Sono persino riuscito a seguire la documentazione per la persistenza del grano e a creare la mia implementazione CosmosDB (SQL API) di IGrainStorage.
Promemoria
Anche i promemoria sono facili da impostare. Finché non ho provato a configurare la persistenza reale per loro. A questo punto della mia ricerca, sto cercando di tenere tutto ordinato e di memorizzare tutto in ComsosDB. Purtroppo, non riesco a far funzionare affatto il pacchetto di promemoria di persistenza di Orleans. Alla fine ho dovuto passare al pacchetto AzureStorage. Quindi ora i miei dati sono metà nell'account SQL API e metà nell'account API della tabella.
Flussi
È lì che non è andata bene. A Orleans, i flussi sono identificati da un GUID e da uno spazio di nomi opzionale. Sono sicuro che ci sia un buon motivo per cui i flussi devono essere identificati da una GUID, ma wow, è poco pratico.
Sono molto frustrato dagli stream perché sono riuscito a crearli facilmente, ma una volta che mi fermo e riavvio il progetto e attivo un nuovo evento, tutto si blocca.
Segue un'informazione molto preziosa, dato che mi ci sono volute 8 ore per fare reverse engineering del codice di Orleans per capirlo:
Quando un grano è un abbonato a streaming, deve chiamare ResumeAsync sull'handle dell'abbonamento nel suo metodo OnActivateAsync, altrimenti si bloccherà con un errore non riconosciuto.
Ho anche avuto il problema che lo stesso abbonamento fosse duplicato, quindi ho usato il codice per cancellare tutti gli abbonamenti del grano e poi l'ho ricreato:
Altri punti su Orleans / Consigli
Gli streams funzionano bene con Azure Event Hubs (tramite AddEventHubStreams).
Non usare / o altri caratteri speciali nel nome Grain dell'API SQL di CosmosDB!
Conclusione di Orleans
Mi piace Orleans e penso che abbia del potenziale. Tuttavia, la curva di apprendimento è molto ripida. A causa della mia lunga lotta con lo streaming, non ho tempo per studiare come funzionano i cluster/deployment.
Dapr
Ho trovato Dapr cercando alternative a Orleans. È un po' strano che sia anche un progetto sponsorizzato da Microsoft. Forse sono qui per adottare un approccio di sopravvivenza del più adatto. Se sì, penso che Dapr sarà un sopravvissuto.
Innanzitutto, il design basato su REST/gRPC di Dapr permette di implementare gli attori utilizzando qualsiasi linguaggio di programmazione. Ho anche trovato banale eseguire tutto (partecipanti, stati, timer, promemoria, eventi) su un'unica istanza Rederis. Inoltre, mi ci è voluto solo circa un terzo del tempo per iniziare a usare Dapr. Un tempo di avvio così rapido è dovuto all'eccellente documentazione di Dapr.
Attori / Timer / Promemoria
Ho appena detto che la documentazione di Dapr è ottima? Beh, è ovunque, tranne che negli esempi JavaScript. Passo la maggior parte del tempo su Dapr, cercando di capire come richiamare i metodi sugli attori. Il codice per l'esempio Dapr Javascript è il seguente:
Questo è chiaramente superato. Ho dovuto passare molto tempo a convincere queste tre righe attraverso l'esplorazione del codice test/esempio di Dapr
Gli esempi di codice per ottenere o impostare lo stato hanno problemi simili, quindi ho creato un problema su GitHub per loro.
A parte questi piccoli problemi, preparare gli attori è una passeggiata.
Impostare timer e promemoria per il mio cast è anche molto facile.
Stato
Sono riuscito a configurare Dapr per far persistere con Postgres molto facilmente.
Una cosa che ho notato è che potrebbero esserci problemi di scalabilità nel modo in cui vengono memorizzati i promemoria. Dapr memorizza tutti gli avvisi per un tipo specifico di partecipante in un singolo array JSON. Cosa succede se qualcuno ha una marea di promemoria?
Altri punti da prendere / consigli su Dapr
Una cosa che ho notato navigando nel codice dell'SDK JavaScript è che nel codice non ci sono quasi tutti i commenti. Questo rende quasi impossibile capire qualcosa. Ad esempio, nel metodo addOrUpdateState del gestore di stato, c'è un terzo parametro chiamato updateValueFactory. Se nel codice non ci sono commenti, è quasi impossibile capire a cosa serva il richiamo.
Non sono nemmeno sicuro di quanto mi piaccia il comando "dapr init" che cerca di configurare ed eseguire un container Redis per me. E se avessi già un contenitore Redis? E se volessi usare postgres invece? Non riesco a trovare documentazione che spieghi come cambiare la funzione DAPR Init.
Una nota per chiunque abbia difficoltà a usare pubsub. Devi usare "dapr run" per gestire sia il tuo editore che l'abbonato:
Per gli attori e pubsub, tieni presente che è importante usare il parametro --app-port per far sapere a dapr su quale porta il tuo servizio è in esecuzione. Gli eventi pubsub e le chiamate degli attori vengono inviati al tuo servizio dal sidecar Dapr tramite chiamate http, quindi deve sapere dove inviarli:
Ho testato un piccolo "cluster" Dapr self-hosted avviando la mia istanza di abbonato pubsub su due macchine diverse della mia rete domestica. Ha semplicemente funzionato!
Conclusione Dapr
Se vuoi conoscere altre idee su applicazioni distribuite o attori virtuali, ti consiglio di iniziare con Dapr. Orleans è stata la pioniera originale, mentre Dapr è stato un reboot che ha portato le cose a un livello superiore.
Link originale:Il login del link ipertestuale è visibile.
|