Vantaggi di Orleans
I principali vantaggi di Orleans sono:
- Produttività per sviluppatori, anche per i programmatori non esperti.
- Scalabilità trasparente per impostazione predefinita senza alcun impegno speciale da parte del programmatore.
Produttività degli sviluppatori
Il modello di programmazione Orleans aumenta la produttività dei programmatori esperti e non esperti fornendo le astrazioni, le garanzie e i servizi di sistema seguenti.
Paradigma di programmazione orientata agli oggetti (OOP) familiare
I grani sono classi .NET che implementano interfacce di granularità .NET dichiarate con metodi asincroni. I grani appaiono al programmatore come oggetti remoti i cui metodi possono essere richiamati direttamente. Questo fornisce al programmatore il paradigma OOP familiare trasformando le chiamate di metodo in messaggi, indirizzandole agli endpoint giusti, richiamando i metodi della granularità di destinazione e gestendo in modo trasparente gli errori e i casi d’angolo.
Esecuzione a thread singolo di grani
Il runtime garantisce che una granularità non venga mai eseguita su più thread alla volta. In combinazione con l'isolamento di altri grani, il programmatore non affronta mai la concorrenza a livello di granularità e non deve mai usare blocchi o altri meccanismi di sincronizzazione per controllare l'accesso ai dati condivisi. Questa funzionalità rende da sola lo sviluppo di applicazioni distribuite trattabili per i programmatori non esperti.
Attivazione trasparente
Il runtime attiva una granularità solo quando è presente un messaggio da elaborare. Questo separa in modo pulito il concetto di creazione di un riferimento a un grano, che è visibile e controllato dal codice dell'applicazione, e l'attivazione fisica della granularità in memoria, che è trasparente per l'applicazione. Ciò è simile alla memoria virtuale in quanto decide quando "uscire dalla pagina" (disattivare) o "entrare nella pagina" (attivare) un grano; l'applicazione ha accesso ininterrotto all'intero "spazio di memoria" dei grani creati logicamente, indipendentemente dal fatto che si trovino nella memoria fisica in un determinato momento.
L'attivazione trasparente consente il bilanciamento del carico dinamico e adattivo tramite posizionamento e migrazione di grani nel pool di risorse hardware. Questa funzionalità è un miglioramento significativo del modello di attore tradizionale, in cui la durata dell'attore è gestita dall'applicazione.
Trasparenza della posizione
Un riferimento granulare (oggetto proxy) usato dal programmatore per richiamare i metodi della granularità o passare ad altri componenti contiene solo l'identità logica della granularità. La conversione dell'identità logica della granularità nella posizione fisica e il routing corrispondente dei messaggi viene eseguito in modo trasparente dal runtime Orleans.
Il codice dell'applicazione comunica con i grani mentre ignora la loro posizione fisica, che può cambiare nel tempo a causa di errori o gestione delle risorse, o perché una granularità viene disattivata al momento della chiamata.
Integrazione trasparente con un archivio permanente
Orleans consente il mapping dichiarativo dello stato in memoria di una granularità a un archivio permanente. Sincronizza gli aggiornamenti, garantendo in modo trasparente che i chiamanti ricevano i risultati solo dopo il completo aggiornamento dello stato persistente. L'estensione e/o la personalizzazione del set di provider di archiviazione permanenti esistenti disponibili è semplice.
Propagazione automatica degli errori
Il runtime propaga automaticamente gli errori non gestiti nella catena di chiamate con la semantica di try/catch asincrona e distribuita. Di conseguenza, gli errori non vengono persi all'interno di un'applicazione. Ciò consente al programmatore di inserire la logica di gestione degli errori nelle posizioni appropriate, senza il lavoro noioso di propagazione manuale degli errori a ogni livello.
Scalabilità trasparente per impostazione predefinita
Il modello di programmazione Orleans è progettato per guidare il programmatore lungo un percorso di probabile successo nel ridimensionare un'applicazione o un servizio attraverso diversi ordini di grandezza. Questa operazione viene eseguita incorporando procedure consigliate e modelli collaudati e fornendo un'implementazione efficiente delle funzionalità di sistema di livello inferiore.
Ecco alcuni fattori chiave che consentono scalabilità e prestazioni:
Partizionamento implicito con granularità fine dello stato dell'applicazione
Usando grani come entità indirizzabili direttamente, il programmatore suddivide in modo implicito lo stato complessivo dell'applicazione. Anche se il modello di programmazione Orleans non prevede quanto deve essere grande o piccolo un grano, nella maggior parte dei casi ha senso avere un numero relativamente elevato di milioni di grani – o più – con ognuno che rappresenta un'entità naturale dell'applicazione, ad esempio un account utente o un ordine di acquisto.
Con i grani indirizzabili singolarmente e la loro posizione fisica astratta dal runtime, Orleans ha un'enorme flessibilità nel bilanciamento del carico e nella gestione delle aree calde in modo trasparente e generico senza alcun pensiero da parte dello sviluppatore dell'applicazione.
Gestione delle risorse adattiva
I grani non presuppongono la località di altri grani mentre interagiscono con loro. A causa di questa trasparenza della posizione, il runtime può gestire e regolare l'allocazione delle risorse hardware disponibili in modo dinamico. Il runtime esegue questa operazione prendendo decisioni dettagliate sul posizionamento e sulla migrazione di grani nel cluster di calcolo in reazione ai modelli di carico e di comunicazione, senza errori nelle richieste in ingresso. Creando più repliche di un particolare livello di granularità, il runtime può aumentare la velocità effettiva della granularità senza apportare modifiche al codice dell'applicazione.
Comunicazione multiplexed
I grani in Orleans hanno endpoint logici e la messaggistica tra di esse è multiplexing in un set fisso di connessioni fisiche all-to-all (socket TCP). In questo modo il runtime può ospitare milioni di entità indirizzabili con un sovraccarico del sistema operativo ridotto per granularità. Inoltre, l'attivazione e la disattivazione di una granularità non comportano costi di registrazione/annullamento della registrazione di un endpoint fisico, ad esempio una porta TCP o un URL HTTP o anche la chiusura di una connessione TCP.
Pianificazione efficiente
Il runtime pianifica l'esecuzione di un numero elevato di grani a thread singolo usando il pool di thread .NET, altamente ottimizzato per le prestazioni. Con il codice granulare scritto nello stile non bloccante basato su continuazione (un requisito del modello di programmazione Orleans), il codice dell'applicazione viene eseguito in modo "cooperativo" molto efficiente senza conflitti. In questo modo il sistema può raggiungere una velocità effettiva elevata ed essere eseguito a un utilizzo molto elevato della CPU (fino al 90%+) con grande stabilità.
Il fatto che la crescita del numero di grani nel sistema e un aumento del carico non comporta thread aggiuntivi o altre primitive del sistema operativo contribuisce alla scalabilità dei singoli nodi e dell'intero sistema.
Asincronia esplicita
Il modello di programmazione Orleans rende esplicita la natura asincrona di un'applicazione distribuita e guida i programmatori a scrivere codice asincrono non bloccanti. In combinazione con la messaggistica asincrona e la pianificazione efficiente, ciò consente un elevato grado di parallelismo distribuito e velocità effettiva complessiva senza l'uso esplicito del multithreading.