Modello agente supervisore di pianificazione

Coordinare un set di azioni distribuite come singola operazione logica in modo che l'operazione abbia esito positivo o negativo. Gestire gli errori in modo trasparente oppure annullare il lavoro completato. Questo approccio aggiunge resilienza ai sistemi distribuiti recuperando da eccezioni temporanee, errori di lunga durata e errori di processo che interrompono flussi di lavoro con più passaggi orchestrati tra servizi e risorse remoti.

Contesto e problema

Le applicazioni spesso eseguono attività che si estendono su più passaggi e alcuni passaggi possono richiamare servizi remoti o accedere a risorse remote nell'orchestrazione della logica dell'applicazione. L'interazione con qualsiasi elemento esterno al processo locale espone l'attività a un intervallo di modalità di errore. La logica di orchestrazione deve gestire queste modalità di errore senza perdere l'integrità dell'operazione nel suo complesso.

È possibile gestire situazioni semplici, ad esempio errori temporanei che si risolvono autonomamente, usando approcci come il modello di ripetizione dei tentativi. Quando i guasti sono più persistenti o quando l'orchestratore stesso si guasta, il sistema deve ripristinare uno stato coerente a partire da record persistenti e garantire l'integrità dell'operazione complessiva.

Soluzione

Il modello Supervisore agente di pianificazione coordina un'attività distribuita a più passaggi tramite tre attori logici. Questi attori orchestrano i passaggi da eseguire come parte dell'attività complessiva e gestiscono le esecuzioni riuscite e non riuscite.

Scheduler

Il Scheduler organizza le fasi che compongono l'attività e ne coordina l'esecuzione. Scheduler è responsabile di combinare i passaggi in una pipeline o in un flusso di lavoro e di eseguirli nell'ordine corretto. Con l'avanzamento di ogni passaggio, l'Utilità di pianificazione registra lo stato, ad esempio il passaggio non ancora avviato, l'esecuzione dei passaggi o il passaggio completato. Lo stato specifica anche un'ora di completamento complete-by che limita il tempo che la fase può richiedere.

Quando una fase richiede un servizio o una risorsa remota, lo Scheduler invoca un Agent appropriato e gli passa i dettagli del lavoro. Lo Scheduler comunica in genere con gli agenti tramite messaggi asincroni di richiesta/risposta, spesso implementati tramite code. È invece possibile usare altre tecnologie di messaggistica distribuita.

Note

L'Utilità di pianificazione svolge una funzione simile al ruolo di Gestore processi nel pattern Process Manager. Un motore di workflow controllato dallo Scheduler in genere definisce e implementa il workflow, disaccoppiando la logica di business del workflow dallo Scheduler stesso.

Agente

Agent racchiude una chiamata a un servizio remoto o l'accesso a una risorsa remota a cui fa riferimento una fase di un'attività. Ogni Agent incapsula in genere le chiamate verso un singolo servizio o una singola risorsa e implementa la corretta gestione degli errori e la logica di ritentativo entro il tempo di completamento imposto dallo Scheduler. Quando entra in gioco la logica di ritentativo, l'agente trasmette un identificatore stabile attraverso tutti i tentativi di ritentativo. Un servizio downstream può usarlo per la deduplicazione.

Se passaggi diversi nel flusso di lavoro usano servizi o risorse diversi, ogni passaggio può fare riferimento a un agente diverso. Quella mappatura è un dettaglio di implementazione del pattern. Per indicazioni sulla progettazione di strategie di ripetizione dei tentativi, vedere Procedure consigliate per la gestione degli errori temporanei.

Supervisore

Il supervisore monitora lo stato dei passaggi esibiti dall'Utilità di pianificazione. Il Supervisor viene eseguito periodicamente alla frequenza specificata dal workload ed esamina lo stato della fase registrato dallo Scheduler. Se il supervisore rileva i passaggi che hanno superato il timeout o l'esito negativo, dispone dell'agente appropriato per ripristinare il passaggio oppure attiva un'altra azione correttiva che potrebbe includere la modifica dello stato del passaggio. Il supervisore richiede solo queste azioni di ripristino. L'Utilità di pianificazione e gli Agenti li implementano.

Interazioni

Scheduler, Agent e Supervisor sono componenti logici e la loro implementazione fisica dipende dalla tecnologia utilizzata. Ad esempio, è possibile implementare diversi agenti logici come parte di un singolo servizio Web o come attività all'interno dello stesso ruolo di lavoro ospitato.

L'utilità di pianificazione tiene traccia dell'avanzamento dell'attività e dello stato di ogni passaggio in un archivio dati persistente denominato archivio di stato. Il supervisore usa queste informazioni per determinare se un passaggio non è riuscito. Il diagramma seguente illustra la relazione tra l'Utilità di pianificazione, gli agenti, il Supervisore e l'archivio degli stati.

Diagramma che mostra lo Scheduler, gli agenti e il supervisore che interagiscono tramite un archivio di stato durevole condiviso.

In alto a sinistra, il pianificatore organizza ed esegue i passaggi. Una linea a doppia freccia con l’etichetta "Lo Scheduler richiede all’Agent di accedere a una risorsa remota" va verso un Agent sulla destra, e una linea a doppia freccia con l’etichetta "L’Agent accede a una risorsa remota o a un servizio" punta dall’Agent a una risorsa remota. Di seguito, le linee a doppia freccia puntano dall'Utilità di pianificazione a un altro agente e quindi a un servizio remoto. Un'altra linea a doppia freccia etichettata "Scheduler mantiene lo stato dello step" scende fino all'archivio degli stati. Una linea a doppia freccia etichettata "Il Supervisore monitora lo stato della fase" collega l'archivio di stato e il Supervisore, alla sua destra. Una freccia con l’etichetta "Il Supervisor richiede di ripetere il passaggio" punta dal Supervisor verso l’alto e a sinistra, fino allo Scheduler.

  • L'Utilità di pianificazione organizza ed esegue i passaggi che costituiscono l'attività come flusso di lavoro.
  • Un passaggio del flusso di lavoro può inviare una richiesta a un agente per accedere a una risorsa remota o richiamare un servizio remoto. Le richieste e le risposte vengono in genere inviate in modo asincrono.
  • Un agente accede alla risorsa o al servizio remoto. L'agente deve prevedere la gestione degli errori e una logica di ritentativo.
  • Lo Scheduler mantiene aggiornato lo stato di ogni passaggio nell'archivio di stato quando inizia e quando si completa.
  • Il Supervisore monitora lo stato delle fasi nell'archivio degli stati e potrebbe richiedere l'aggiornamento dello stato di una fase.
  • Il supervisore richiede all'utilità di pianificazione di ripetere un passaggio non riuscito.

Quando l'applicazione è pronta per l'esecuzione di un'attività, invia una richiesta all'utilità di pianificazione. L'Utilità di pianificazione registra lo stato iniziale per l'attività e i relativi passaggi, ad esempio il passaggio non ancora avviato, nell'archivio stati e quindi avvia l'esecuzione delle operazioni definite dal flusso di lavoro. Quando l'Utilità di pianificazione avvia ogni passaggio, aggiorna lo stato di tale passaggio, ad esempio il passaggio in esecuzione, nell'archivio stati.

Se un passaggio fa riferimento a una risorsa o un servizio remoto, l'utilità di pianificazione invia un messaggio all'agente appropriato. Il messaggio contiene le informazioni necessarie all'Agent per invocare il servizio o accedere alla risorsa, insieme al termine entro cui completare l'operazione e al numero consentito di tentativi.

Un agente può implementare qualsiasi logica di ritentativo appropriata alla propria attività, ma se l'agente non completa il proprio lavoro entro il tempo previsto per il completamento, l'Utilità di pianificazione presume che l'operazione non sia riuscita e smette di attendere una risposta. L'agente deve rispettare la scadenza e non deve avviare nuovi effetti collaterali dopo la scadenza, anche se il lavoro già in corso potrebbe continuare.

Se l'agente completa l'operazione, restituisce una risposta allo Scheduler. L'Utilità di pianificazione aggiorna lo stato, ad esempio a passaggio completato, e avvia il passaggio successivo. Questo processo continua fino al completamento dell'intera attività.

L'Utilità di pianificazione deve ignorare qualsiasi risposta in ritardo e l'Agente non deve tentare il ripristino del flusso di lavoro in autonomia. Se l'agente stesso non riesce, anche l'Utilità di pianificazione non riceve alcuna risposta. Lo stato nell'archivio di stato intenzionalmente non distingue una fase che va in timeout da una fase che fallisce.

Quando un passaggio va in timeout o non riesce, il record dell'archivio di stato continua a mostrare il passaggio come in esecuzione, ma con un termine di completamento scaduto. Il supervisore analizza i record in questa condizione e dispone il ripristino.

Il Supervisore deve anche impedire che lo stesso passaggio venga ripetuto all'infinito. Il supervisore mantiene un numero di tentativi per ogni fase, insieme alle informazioni sullo stato, nell'archivio dello stato. Se il conteggio supera una soglia predefinita, il supervisore può essere impostato per attendere un periodo prolungato prima di chiedere all'Utilità di pianificazione di ritentare il passaggio, nel caso in cui l'errore sottostante venga cancellato durante tale intervallo.

Una possibile strategia del supervisore consiste nell'estendere il valore di completamento entro e nell'inviare un messaggio allo Scheduler che identifichi la fase andata in timeout, in modo che lo Scheduler possa tentare nuovamente di eseguirla. Questa progettazione richiede che la logica del passaggio sia idempotente, perché la stessa operazione potrebbe essere eseguita più volte.

In alternativa, il supervisore può chiedere all'utilità di pianificazione di annullare l'intera attività attivando una transazione di compensazione. Questo approccio dipende dal fatto che lo Scheduler e gli agenti forniscano informazioni sufficienti per implementare operazioni di compensazione per ogni fase già completata con successo. Il log di compensazione richiede l'ordinamento e la durabilità, perché le operazioni di compensazione vengono in genere eseguite nell'ordine inverso dei passaggi completati. Un'operazione di compensazione che a sua volta non riesce lascia l'attività in uno stato che non è né completata né ripristinata correttamente. L'archivio degli stati deve essere in grado di rappresentare questa condizione in modo che gli operatori possano individuarla e analizzarla.

Note

Il supervisore non monitora l'utilità di pianificazione e gli agenti e li riavvia in caso di errore. Tale ruolo appartiene all'infrastruttura di hosting. Il supervisore non deve inoltre conoscere le operazioni aziendali eseguite dall'Utilità di pianificazione, incluso come compensare se hanno esito negativo. Tale conoscenza appartiene alla logica del flusso di lavoro eseguita dall'Utilità di pianificazione. Il supervisore è responsabile solo del rilevamento dell'esito negativo di un passaggio e dell'organizzazione del passaggio da ripetere o dell'intera attività che contiene il passaggio non riuscito da annullare.

In un'implementazione effettiva di questo modello, più istanze dell'Utilità di pianificazione possono essere eseguite contemporaneamente, ognuna delle quali gestisce un subset di attività. Il sistema può anche eseguire più istanze di ogni Agente o di più Supervisori. Quando più supervisori sono attivi, i supervisori devono coordinare in modo da non competere per recuperare lo stesso passaggio o attività non riuscito. Il modello elezione leader è un modo per coordinare i supervisori.

Il vantaggio principale di questo schema è che il sistema rimane resiliente sia ai guasti transitori sia a quelli non recuperabili, e può essere progettato in modo da essere autoriparante. Se un agente o l'utilità di pianificazione non riesce, è possibile avviare una nuova istanza e il supervisore può organizzare la ripresa dell'attività interessata. Se il supervisore stesso ha esito negativo, un'altra istanza può assumere la posizione in cui è stata arrestata la precedente. Quando il Supervisor viene eseguito in base a una pianificazione, una nuova istanza si avvia automaticamente al successivo intervallo pianificato. È anche possibile replicare l'archivio di stato per una maggiore resilienza.

Problemi e considerazioni

Quando si decide come implementare questo modello, tenere presente quanto segue:

  • Complessità dell'implementazione. Questo modello è difficile da implementare e richiede test approfonditi di ogni modalità di errore che il sistema può sperimentare. Pianificare i test di iniezione di errore insieme ai test funzionali.

  • Amplificazione dei tentativi. Limiti indipendenti di ripetizione a livello di agente, runtime di orchestrazione, libreria client, messaggistica e supervisore moltiplicano il numero di chiamate a una dipendenza che presenta un errore. Assegna allo Scheduler il ruolo di responsabile di un budget persistente end-to-end per i nuovi tentativi e configura o disabilita i nuovi tentativi negli altri livelli in modo che il numero massimo complessivo non possa superare tale budget.

  • Controllo di ammissione. Lo schema non limita quanto lavoro può essere in corso contemporaneamente. Poiché lo Scheduler è progettato per non perdere mai il lavoro che accetta, un servizio downstream lento o malfunzionante provoca un accumulo crescente di record di elaborazione, anziché una pressione a monte visibile al client che invia le richieste. Il percorso di invio richiede un proprio controllo di ammissione, ad esempio una coda delimitata, un limite per le attività simultanee in corso o il rifiuto di nuovi invii quando il backlog in sospeso supera una soglia. Questo meccanismo di backpressure contribuisce a garantire che un incidente a valle non provochi silenziosamente un backlog illimitato dello state store.

  • Durabilità dello stato di ripristino. La logica di recupero e ritentativo dello Scheduler è complessa e dipende dallo stato mantenuto nell'archivio dello stato. Potrebbe anche essere necessario registrare, in un archivio persistente, le informazioni necessarie per gestire l'esecuzione di una transazione di compensazione, e la stessa transazione di compensazione può non riuscire. Considerare l'archivio di stato e qualsiasi log delle transazioni di compensazione come asset durevoli di prima classe. Questi asset devono sopravvivere allo Scheduler, agli Agent e al Supervisor, e devono poter essere recuperati indipendentemente dai worker che vi scrivono.

    Important

    Il log di compensazione deve ereditare la classificazione dei dati di cui deve tenere traccia. Se un passaggio accetta dati dei clienti o di pagamento, il log della transazione di compensazione eredita tale livello di sensibilità e le relative regole di conservazione.

  • Problema di doppia scrittura. L'invio di un'attività comporta in genere più di una scrittura persistente. Ad esempio, un'attività potrebbe dover scrivere sia una voce relativa all'applicazione in un database aziendale sia un record iniziale nell'archivio di stato. Queste scritture non condividono una transazione, quindi se viene completata una sola scrittura, un record dell'applicazione potrebbe non avere alcun record dell'archivio stato o un record dell'archivio stati potrebbe non avere alcun record dell'applicazione. Lo schema attuale, di per sé, non risolve questo problema di doppia scrittura. Le soluzioni comuni includono la scrittura all'interno di un'orchestrazione durevole con un'eliminazione compensativa in caso di fallimento, l'applicazione del pattern Transactional Outbox oppure l'uso di un identificatore stabile, ad esempio l'ID attività dell'applicazione stessa, per rendere ogni scrittura ripetibile in modo sicuro.

  • Controllo delle versioni del flusso di lavoro e dello stato. Le attività a esecuzione prolungata possono estendersi su distribuzioni, quindi le modifiche apportate alla logica del flusso di lavoro o allo stato persistente possono impedire la riproduzione, il ripristino o la compensazione per il lavoro in corso. Assegna una versione a entrambi i contratti e mantieni il codice compatibile e la gestione dello stato finché nessuna attività attiva dipende da essi.

  • Esiti della compensazione Una transazione di compensazione può essere completata, non riuscita o bloccata. La macchina a stati gestita dallo Scheduler deve rappresentare tutti questi stati. Se Error è l'unico stato terminale, una compensazione bloccata è identica a un passaggio non riuscito prima dell'esecuzione della compensazione e gli operatori perdono il segnale che devono intervenire. Distinguere la compensazione in corso, il risarcimento completato e la compensazione non è riuscita nello schema dell'archivio di stato anziché comprimerli in un singolo stato errore .

  • Cadenza del supervisore. La frequenza con cui eseguire il Supervisor è un compromesso intenzionale. Deve essere eseguito con una frequenza sufficiente da evitare che le fasi non riuscite o andate in timeout blocchino il lavoro per un periodo prolungato, ma non con una frequenza tale da diventare una fonte di carico e di costi per l'archivio di stato. Ottimizzare l'intervallo rispetto alla durata tipica del passaggio e al ritardo di rilevamento accettabile per un passaggio bloccato e rivederlo man mano che aumenta il volume del flusso di lavoro.

  • Idempotenza dello step Un agente potrebbe eseguire un passaggio più volte. Ad esempio, il Supervisor potrebbe posticipare il termine di completamento e chiedere allo Scheduler di rieseguire una fase la cui esecuzione originale ha già prodotto un effetto che lo Scheduler non ha mai rilevato. Pertanto, la logica che implementa ogni passaggio deve essere idempotente.

  • Visibilità operativa. Il comportamento del pattern in fase di esecuzione si manifesta nelle transizioni dello state store piuttosto che nelle risposte sincrone. Gli operatori possono vedere solo ciò che l'archivio di stato e i worker emettono. Decidi cosa devono generare lo Scheduler, gli agenti e il supervisore e quali soglie debbano attivare gli avvisi.

  • Riavvio e ripristino del pianificatore. Se l'Utilità di pianificazione viene riavviata dopo un errore o il flusso di lavoro in cui l'utilità di pianificazione è in esecuzione termina in modo imprevisto, l'Utilità di pianificazione deve essere in grado di determinare lo stato di qualsiasi attività gestita quando non è riuscita e riprendere l'attività da quel punto. I dettagli di implementazione di questo ripristino sono in genere specifici del sistema. Ad esempio, uno Scheduler basato su un runtime di orchestrazione con checkpoint può fare affidamento sul runtime per rieseguire la cronologia e riprendere l'esecuzione, mentre uno Scheduler personalizzato deve ricostruire direttamente dall'archivio di stato lo stato delle operazioni in corso. Se non è possibile recuperare un'attività, potrebbe essere necessario annullare il lavoro già eseguito per tale attività, che può richiedere una transazione di compensazione.

Quando usare questo modello

Usare questo modello quando:

  • Un processo viene eseguito in un carico di lavoro distribuito e deve rimanere resiliente sia agli errori di comunicazione che agli errori operativi tra i servizi e le risorse che coordina.

  • I processi in background orchestrano flussi di lavoro a più passaggi i cui passaggi coinvolgono servizi o risorse remoti e i flussi di lavoro nel suo complesso devono essere completati o annullati correttamente. Esempi comuni includono l'elaborazione degli ordini e il provisioning delle risorse. Per altre informazioni, vedere Procedure consigliate per i processi in background.

Questo modello potrebbe non essere adatto quando:

  • L'attività non richiama i servizi remoti o accede alle risorse remote. Non esiste alcuna superficie di guasto distribuita da mitigare per i ruoli Scheduler, Agent e Supervisor. Il sovraccarico di coordinamento del modello aggiunge costi senza alcun vantaggio di resilienza.

Progettazione del carico di lavoro

Valutare come usare il modello Scheduler-Agent-Supervisor nella progettazione di un carico di lavoro per raggiungere gli obiettivi e i principi descritti nei pilastri di Azure Well-Architected Framework. La tabella seguente fornisce indicazioni su come questo modello supporta gli obiettivi di ogni pilastro.

Pilastro Come questo modello supporta gli obiettivi di pilastro
decisioni di progettazione dell'affidabilità consentono al carico di lavoro di diventare resiliente a un malfunzionamento e assicurano che ripristini a uno stato completamente funzionante dopo che si verifica un guasto. Questo modello usa un archivio di stato persistente e un Supervisore periodico per rilevare le fasi che sono andate in timeout o non sono riuscite e per avviare il ripristino.

- Ridondanza RE:05
- RE:07 Autoconservazione
l'efficienza delle prestazioni consente al carico di lavoro soddisfare in modo efficiente le richieste tramite ottimizzazioni di ridimensionamento, dati e codice. Questo modello separa l'orchestrazione di attività di lunga durata e multifase dagli Agenti che eseguono i passaggi, in modo che i passaggi possano essere assegnati agli Agenti che hanno capacità disponibile. Il lavoro con priorità più alta può essere pianificato prima del lavoro con priorità più bassa quando l'implementazione fornisce un segnale di priorità esplicito.

- PE:05 Ridimensionamento e partizionamento
- Flussi critici PE:09

Se questo modello introduce compromessi all'interno di un pilastro, considerarli contro gli obiettivi degli altri pilastri.

Esempio

Questo esempio distribuisce un'applicazione Web che implementa un sistema di e-commerce in Microsoft Azure. Gli utenti consultano i prodotti ed effettuano ordini tramite un front-end web, e i processi in background nel flusso di elaborazione degli ordini invocano un servizio remoto incline a guasti transitori e più persistenti. L'elaborazione degli ordini implementa il modello supervisore agente di pianificazione usando Durable Functions, bus di servizio di Azure e Azure Cosmos DB.

Un'attività di invio scrive nel database degli ordini e in un archivio di stato di Cosmos DB; un orchestratore di Durable Functions prende in carico i record di stato in sospeso e instrada il lavoro a un agente tramite una coppia di code di richiesta e risposta di bus di servizio; e un supervisore analizza l'archivio di stato alla ricerca di orari CompleteBy scaduti.

Il diagramma seguente mostra una visualizzazione generale della soluzione Azure.

Diagramma che mostra l'esempio di soluzione di elaborazione degli ordini di e-commerce.

  1. L'applicazione invia una richiesta a una coda per gestire l'ordine.
  2. Il processo di inoltro recupera le richieste, inserisce i dettagli dell'ordine nel database degli ordini e genera un record per l'ordine nell'archivio di stato.
  3. L'Utilità di pianificazione cerca un ordine con LockedBy impostato su Null nell'archivio stati e la logica del flusso di lavoro nell'Utilità di pianificazione gestisce l'ordine.
  4. La logica del flusso di lavoro invia richieste agli Agenti e ne riceve risposte tramite code di messaggi.
  5. Le attività del flusso di lavoro usano Agenti per richiamare il servizio remoto.
  6. Il supervisore cerca gli ordini con un valore scaduto CompleteBy e aggiorna questo valore per consentire all'Utilità di pianificazione di ripetere il processo.

Invio

Quando un cliente effettua un ordine, il front-end Web invia un messaggio di ordine a una coda di bus di servizio. Una funzione di invio riceve il messaggio in modalità PeekLock, inserisce i dettagli dell'ordine nel database degli ordini e crea un record di stato per il processo dell'ordine.

Poiché il database degli ordini e il database creato con Azure Cosmos DB sono risorse diverse e non condividono una transazione, la funzione considera ogni scrittura come idempotente indipendentemente. La funzione usa l'ID ordine come chiave stabile, crea un record quando manca e accetta un record esistente solo dopo aver verificato che i dati dell'ordine non modificabile corrispondano al messaggio. I dati in conflitto inducono la funzione a spostare il messaggio nella coda dei messaggi non recapitabili e ad avvisare un operatore, anziché sovrascrivere un record.

Il record contiene i campi seguenti:

Campo Description
OrderID L'ID dell'ordine nel database degli ordini, utilizzato come ID del documento e chiave di partizione di Azure Cosmos DB.
LockedBy ID istanza specifica del tentativo dell'orchestrazione che gestisce l'ordine. Potrebbero essere in esecuzione più orchestrazioni dello Scheduler, ma una transizione di stato condizionale consente che sia attivo un solo tentativo di prendere in carico un ordine.
CompleteBy Ora di elaborazione dell'ordine.
ProcessState Stato corrente dell'attività che gestisce l'ordine. Gli stati possibili sono:
- Pending: l'ordine viene creato ma l'elaborazione non è stata avviata.
- Processing: l'ordine è in corso di elaborazione.
- Processed: Ordine elaborato correttamente.
- Error: l'elaborazione dell'ordine non è riuscita.
FailureCount Numero di tentativi di elaborazione non riusciti o andati in timeout registrati per l'ordine.

Quando l'attività di invio scrive per la prima volta il record, copia OrderID dal nuovo ordine, imposta LockedBy e CompleteBy su null, imposta ProcessState su Pendinge imposta FailureCount su 0.

Note

In questo esempio la logica di gestione degli ordini è intenzionalmente semplice e ha un unico passaggio che chiama un servizio remoto. In uno scenario multistep più complesso, l'attività di invio creerebbe un record dello state store per ogni passaggio, mantenendo OrderID come chiave di partizione, ma usando un ID elemento univoco come {OrderID}:{StepID}, in modo che Scheduler e Supervisor possano valutare in modo indipendente lo stato di ciascun passaggio.

Scheduling

L'utilità di pianificazione è un agente di orchestrazione Durable Functions. Una funzione di avvio esegue il polling di Azure Cosmos DB per i record in cui LockedBy è null e ProcessState è Pending. La funzione crea un ID di istanza dell'orchestrazione specifico per il tentativo a partire da OrderID e dal numero del tentativo successivo. Un aggiornamento condizionale imposta ProcessState su Processing e LockedBy su quell'ID dell'istanza prima che il componente di avvio pianifichi l'orchestrazione. Questa attestazione impedisce a due starter di pianificare lo stesso tentativo.

Ogni aggiornamento dell'orchestrazione verifica anche che LockedBy corrisponda ancora all'ID dell'istanza. Questo controllo impedisce a un tentativo scaduto di modificare lo stato di un tentativo di sostituzione. Il parallelismo tra ordini deriva dall'esecuzione simultanea di molte istanze di orchestrazione, non dal parallelismo all'interno di un unico ordine. L'orchestrazione imposta CompleteBy e determina il flusso di lavoro.

L'agente di orchestrazione recupera i dettagli dell'ordine dal database degli ordini ed esegue il flusso di lavoro come sequenza di funzioni di attività. Quando un passaggio richiede il servizio remoto, richiama un agente.

Execution

L'agente può essere una funzione di attività quando il lavoro è di breve durata e viene eseguito nella stessa app per funzioni, oppure può essere un worker separato raggiungibile tramite una coppia di code di richiesta/risposta di bus di servizio quando viene eseguito in un runtime diverso o oltre un confine di attendibilità. In entrambi i casi, l'orchestratore mette in competizione un timer durevole con la risposta dell'agente per rilevare la CompleteBy scadenza temporale.

Quando l'agente viene raggiunto su bus di servizio, una funzione attivata dalla coda riceve la risposta e usa il client Durable Functions per generare un evento esterno che include l'ID dell'istanza di orchestrazione e un ID evento stabile. L'orchestratore elimina i duplicati degli eventi esterni abilitando il rilevamento dei duplicati e impostando un valore MessageId stabile per ogni richiesta, in modo che bus di servizio possa eliminare i duplicati introdotti dai nuovi tentativi.

Se l'agente riceve una risposta dal servizio remoto prima che scatti il timer durevole, l'agente restituisce il risultato all'orchestratore. L'orchestratore completa il passaggio e aggiorna ProcessState in Processed solo se LockedBy identifica ancora l'orchestrazione corrente. Se il timer scatta per primo, l’orchestratore considera il passaggio fallito, smette di attendere e completa l’operazione senza modificare il record di stato.

L'agente interrompe in modo cooperativo l'avvio di nuovi effetti collaterali dopo la scadenza, ma il lavoro già in corso potrebbe continuare. Il record dello state-store rimane quindi nello stato Processing con un valore CompleteBy scaduto, consentendo al Supervisor di predisporre il ripristino. Usare l'idempotenza o un fencing token imposto dalla destinazione per evitare che un tentativo sovrapposto duplichi un effetto collaterale o entri in conflitto con esso.

Se l'agente rileva un errore irreversibile e non temporaneo durante il contatto con il servizio remoto, restituisce una risposta di errore all'agente di orchestrazione. L'agente di orchestrazione imposta ProcessState su Error e genera un evento che avvisa un operatore, che può analizzare l'errore e inviare di nuovo il passaggio di elaborazione non riuscito.

Supervisione

Il supervisore interroga periodicamente l'archivio di stato di Azure Cosmos DB per gli ordini con stato Processing e con CompleteBy scaduto. Poiché OrderID è la chiave di partizione, questa query raggiunge ogni partizione fisica anche quando ProcessState e CompleteBy vengono indicizzati. Il processo limita ogni scansione tramite un CompleteBy intervallo di tempo, un numero massimo di risultati e la paginazione tramite token di continuazione, e monitora l'addebito in unità richiesta (RU).

I carichi di lavoro più grandi mantengono un indice di ripristino separato o una coda separata, partizionati in base allo schema di accesso del Supervisor. Quando il supervisore trova un record scaduto, usa un aggiornamento condizionale che verifica il valore scaduto LockedBy prima che incrementi FailureCount. Se FailureCount è inferiore a una soglia configurata, il Supervisor reimposta LockedBy su null, aggiorna CompleteBy con un nuovo tempo di scadenza e reimposta ProcessState su Pending, consentendo allo starter di pianificare un nuovo tentativo. Se FailureCount supera la soglia, il supervisore considera l'errore come non temporaneo, imposta ProcessState su Errore genera un evento che avvisa un operatore.

Note

Il supervisore è ospitato come funzione attivata dal timer quando l'analisi è breve e leggera, oppure come processo pianificato di App contenitore di Azure quando l'analisi richiede un'immagine container personalizzata, un'esecuzione più lunga o sidecar. Entrambe le opzioni vengono eseguite in base a una pianificazione in stile cron e soddisfano il lavoro periodico e di breve durata che il supervisore esegue. Il trigger timer usa un blocco di archiviazione tra istanze con scalabilità orizzontale in un'unica app per le funzioni. Le distribuzioni indipendenti o i processi di Container Apps che possono sovrapporsi utilizzano la rivendicazione di ripristino condizionale descritta in precedenza, oppure possono essere coordinati tramite il pattern Leader Election.

Relazioni sullo stato

L'orchestratore potrebbe anche dover tenere informata l'applicazione che ha inviato l'ordine sui progressi e sullo stato finale, cosa che il diagramma non mostra. L'applicazione e l'orchestratore sono deliberatamente disaccoplate. L'applicazione non sa quale istanza di orchestrazione gestisce l'ordine e l'orchestrazione non sa quale istanza dell'applicazione lo ha inviato. A causa di questo disaccoppiamento, l'orchestratore non può restituire aggiornamenti sullo stato di avanzamento in modo sincrono.

Per comunicare lo stato dell'ordine in risposta, ogni applicazione mittente fornisce la propria coda di risposta privata di bus di servizio con accesso controllato. La richiesta inviata all'attività di invio include l'identificatore della coda, che l'attività di invio registra nel record dell'archivio di stato dell'ordine in modo che l'agente di orchestrazione possa pubblicare nella coda corretta anziché trasmettere. L'agente di orchestrazione invia quindi messaggi di stato, ad esempio la richiesta ricevuta, l'ordine completato o l'ordine non riuscito a tale coda, incluso in OrderID modo che l'applicazione possa correlare ogni messaggio con la richiesta originale.

Tecnologie di supporto

Associare i ruoli logici dello schema ai servizi che soddisfano i requisiti del flusso di lavoro e operativi:

Passaggi successivi

I modelli seguenti possono essere rilevanti anche quando si implementa questo modello:

  • Modello di ripetizione dei tentativi. Un agente può usare questo modello per ripetere in modo trasparente un'operazione che accede a un servizio remoto o a una risorsa e in precedenza non è riuscita. Usarlo quando si prevede che la causa dell'errore sia temporanea e possa essere corretta da un nuovo tentativo.

  • Schema Circuit Breaker. Un agente che si connette a un servizio remoto o a una risorsa può utilizzare questo modello per gestire guasti la cui correzione può richiedere tempi variabili, in modo che le chiamate ripetute non si accumulino verso una dipendenza che è improbabile che risponda.

  • Modello di transazioni di compensazione. Se un'utilità di pianificazione non riesce a completare correttamente il flusso di lavoro, potrebbe essere necessario annullare il lavoro già eseguito. Il pattern della transazione di compensazione descrive come annullare tale lavoro per le operazioni che seguono il modello di coerenza eventuale, comune nei processi aziendali di lunga durata coordinati da uno scheduler.

  • Modello di designazione leader. Quando più istanze di supervisore vengono eseguite contemporaneamente, devono coordinare in modo che non competano per recuperare lo stesso passaggio non riuscito. Il modello Elezione leader descrive come eleggere un singolo coordinatore per tale lavoro.