Hub attività in Funzioni permanenti (Funzioni di Azure)

Un hub attività in Durable Functions è una rappresentazione dello stato corrente dell'applicazione nell'archiviazione, incluso tutto il lavoro in sospeso. Mentre un'app per le funzioni è in esecuzione, lo stato di avanzamento dell'orchestrazione, dell'attività e delle funzioni di entità viene archiviato continuamente nell'hub attività. Ciò garantisce che l'applicazione possa riprendere l'elaborazione in cui è stata interrotta, se deve essere riavviata dopo essere stata temporaneamente arrestata o interrotta per qualche motivo. Consente inoltre all'app per le funzioni di ridimensionare dinamicamente i ruoli di lavoro di calcolo.

Diagramma che mostra il concetto di app per le funzioni e il concetto di hub attività.

Concettualmente, un hub attività archivia le informazioni seguenti:

  • Stati dell'istanza di tutte le istanze di orchestrazione ed entità.
  • Messaggi da elaborare, tra cui
    • eventuali messaggi di attività che rappresentano attività in attesa di esecuzione.
    • tutti i messaggi di istanza in attesa di essere recapitati alle istanze.

La differenza tra i messaggi di attività e di istanza è che i messaggi di attività sono senza stato e possono quindi essere elaborati ovunque, mentre i messaggi di istanza devono essere recapitati a una particolare istanza con stato (orchestrazione o entità), identificata dall'ID istanza.

Internamente, ogni provider di archiviazione può usare un'organizzazione diversa per rappresentare gli stati e i messaggi dell'istanza. Ad esempio, i messaggi vengono archiviati nelle code di Archiviazione di Azure dal provider di Archiviazione di Azure, ma nelle tabelle relazionali dal provider MSSQL. Queste differenze non sono importanti per quanto riguarda la progettazione dell'applicazione, ma alcune di esse possono influenzare le caratteristiche delle prestazioni. Vengono illustrati nella sezione Rappresentazione nell'archiviazione di seguito.

Elementi di lavoro

I messaggi di attività e i messaggi di istanza nell'hub attività rappresentano il lavoro che l'app per le funzioni deve elaborare. Mentre l'app per le funzioni è in esecuzione, recupera continuamente gli elementi di lavoro dall'hub attività. Ogni elemento di lavoro elabora uno o più messaggi. Distinguiamo due tipi di elementi di lavoro:

  • Elementi di lavoro attività: eseguire una funzione di attività per elaborare un messaggio di attività.
  • Elemento di lavoro di Orchestrator: eseguire un agente di orchestrazione o una funzione di entità per elaborare uno o più messaggi di istanza.

I ruoli di lavoro possono elaborare più elementi di lavoro contemporaneamente, soggetti ai limiti di concorrenza configurati per ogni ruolo di lavoro.

Dopo che un ruolo di lavoro completa un elemento di lavoro, esegue il commit degli effetti nell'hub attività. Questi effetti variano in base al tipo di funzione eseguita:

  • Una funzione di attività completata crea un messaggio di istanza contenente il risultato, indirizzato all'istanza dell'agente di orchestrazione padre.
  • Una funzione dell'agente di orchestrazione completata aggiorna lo stato e la cronologia dell'orchestrazione e può creare nuovi messaggi.
  • Una funzione di entità completata aggiorna lo stato dell'entità e può anche creare nuovi messaggi di istanza.

Per le orchestrazioni, ogni elemento di lavoro rappresenta un episodio dell'esecuzione dell'orchestrazione. Un episodio inizia quando vengono elaborati nuovi messaggi per l'agente di orchestrazione. Un messaggio di questo tipo può indicare che l'orchestrazione deve iniziare; oppure può indicare che un'attività, una chiamata di entità, un timer o una suborchestrazione è stata completata; oppure può rappresentare un evento esterno. Il messaggio attiva un elemento di lavoro che consente all'agente di orchestrazione di elaborare il risultato e di continuare con l'episodio successivo. L'episodio termina quando l'agente di orchestrazione viene completato o raggiunge un punto in cui deve attendere nuovi messaggi.

Esempio di esecuzione

Si consideri un'orchestrazione fan-out-in che avvia due attività in parallelo e attende il completamento di entrambe le attività:

[FunctionName("Example")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    Task t1 = context.CallActivityAsync<int>("MyActivity", 1);
    Task t2 = context.CallActivityAsync<int>("MyActivity", 2);
    await Task.WhenAll(t1, t2);
}

Dopo l'avvio di questa orchestrazione da parte di un client, l'app per le funzioni viene elaborata come sequenza di elementi di lavoro. Ogni elemento di lavoro completato aggiorna lo stato dell'hub attività quando esegue il commit. Questa è la procedura:

  1. Un client richiede di avviare una nuova orchestrazione con id istanza "123". Al termine della richiesta, l'hub attività contiene un segnaposto per lo stato di orchestrazione e un messaggio di istanza:

    workitems-illustration-step-1

    L'etichetta ExecutionStarted è uno dei molti tipi di eventi di cronologia che identificano i vari tipi di messaggi ed eventi che partecipano alla cronologia di un'orchestrazione.

  2. Un ruolo di lavoro esegue un elemento di lavoro dell'agente di orchestrazione per elaborare il ExecutionStarted messaggio. Chiama la funzione dell'agente di orchestrazione che avvia l'esecuzione del codice di orchestrazione. Questo codice pianifica due attività e quindi arresta l'esecuzione quando è in attesa dei risultati. Dopo che il ruolo di lavoro esegue il commit di questo elemento di lavoro, l'hub attività contiene

    workitems-illustration-step-2

    Lo stato di runtime è ora Running, sono stati aggiunti due nuovi TaskScheduled messaggi e la cronologia contiene ora i cinque eventi OrchestratorStarted, , ExecutionStartedTaskScheduled, TaskScheduled, OrchestratorCompleted. Questi eventi rappresentano il primo episodio dell'esecuzione di questa orchestrazione.

  3. Un ruolo di lavoro esegue un elemento di lavoro attività per elaborare uno dei TaskScheduled messaggi. Chiama la funzione di attività con input "2". Al termine della funzione di attività, viene creato un TaskCompleted messaggio contenente il risultato. Dopo che il ruolo di lavoro esegue il commit di questo elemento di lavoro, l'hub attività contiene

    workitems-illustration-step-3

  4. Un ruolo di lavoro esegue un elemento di lavoro dell'agente di orchestrazione per elaborare il TaskCompleted messaggio. Se l'orchestrazione è ancora memorizzata nella cache, può semplicemente riprendere l'esecuzione. In caso contrario, il ruolo di lavoro riproduce prima la cronologia per recuperare lo stato corrente dell'orchestrazione. Continua quindi l'orchestrazione, fornendo il risultato dell'attività. Dopo aver ricevuto questo risultato, l'orchestrazione è ancora in attesa del risultato dell'altra attività, quindi ancora una volta interrompe l'esecuzione. Dopo che il ruolo di lavoro esegue il commit di questo elemento di lavoro, l'hub attività contiene

    workitems-illustration-step-4

    La cronologia dell'orchestrazione contiene ora altri tre eventiOrchestratorStarted, , TaskCompleted. OrchestratorCompleted Questi eventi rappresentano il secondo episodio dell'esecuzione di questa orchestrazione.

  5. Un ruolo di lavoro esegue un elemento di lavoro dell'attività per elaborare il messaggio rimanente TaskScheduled . Chiama la funzione di attività con input "1". Dopo che il ruolo di lavoro esegue il commit di questo elemento di lavoro, l'hub attività contiene

    workitems-illustration-step-5

  6. Un ruolo di lavoro esegue un altro elemento di lavoro dell'agente di orchestrazione per elaborare il TaskCompleted messaggio. Dopo aver ricevuto questo secondo risultato, l'orchestrazione viene completata. Dopo che il ruolo di lavoro esegue il commit di questo elemento di lavoro, l'hub attività contiene

    workitems-illustration-step-6

    Lo stato di runtime è ora Completede la cronologia dell'orchestrazione ora contiene altri quattro eventi OrchestratorStarted, , TaskCompleted, ExecutionCompletedOrchestratorCompleted. Questi eventi rappresentano il terzo e ultimo episodio dell'esecuzione di questa orchestrazione.

La cronologia finale per l'esecuzione di questa orchestrazione contiene quindi 12 eventi OrchestratorStarted, , , TaskScheduledExecutionStartedExecutionCompletedTaskCompletedTaskScheduledOrchestratorCompletedOrchestratorCompletedOrchestratorStartedTaskCompletedOrchestratorStarted. OrchestratorCompleted

Nota

La pianificazione illustrata non è l'unica: esistono molte pianificazioni leggermente diverse. Ad esempio, se la seconda attività viene completata in precedenza, entrambi TaskCompleted i messaggi di istanza possono essere elaborati da un singolo elemento di lavoro. In tal caso, la cronologia di esecuzione è un po' più breve, perché sono presenti solo due episodi e contiene i 10 eventi seguenti: OrchestratorStarted, , ExecutionStartedTaskScheduled, TaskScheduled, OrchestratorCompleted, OrchestratorStartedTaskCompleted, , TaskCompleted, , . ExecutionCompletedOrchestratorCompleted

Gestione dell'hub attività

Si esamini ora in dettaglio come vengono creati o eliminati gli hub attività, come usare correttamente gli hub attività durante l'esecuzione di più app per le funzioni e il modo in cui è possibile esaminare il contenuto degli hub attività.

Creazione ed eliminazione

Un hub attività vuoto con tutte le risorse necessarie viene creato automaticamente nell'archiviazione quando un'app per le funzioni viene avviata la prima volta.

Se si usa il provider di Archiviazione di Azure predefinito, non è necessaria alcuna configurazione aggiuntiva. In caso contrario, seguire le istruzioni per configurare i provider di archiviazione per assicurarsi che il provider di archiviazione possa effettuare correttamente il provisioning e accedere alle risorse di archiviazione necessarie per l'hub attività.

Nota

L'hub attività non viene eliminato automaticamente quando si arresta o si elimina l'app per le funzioni. È necessario eliminare manualmente l'hub attività, il relativo contenuto o l'account di archiviazione che lo contiene se non si vogliono più conservare tali dati.

Suggerimento

In uno scenario di sviluppo, potrebbe essere necessario riavviare da uno stato pulito spesso. A tale scopo, è sufficiente modificare il nome dell'hub attività configurato. In questo modo verrà forzata la creazione di un nuovo hub attività vuoto quando si riavvia l'applicazione. Tenere presente che i dati precedenti non vengono eliminati in questo caso.

Più app per le funzioni

Se più app per le funzioni condividono un account di archiviazione, ogni app per le funzioni deve essere configurata con un nome di hub attività separato. Questo requisito si applica anche agli slot di staging: ogni slot di staging deve essere configurato con un nome univoco dell'hub attività. Un singolo account di archiviazione può contenere più hub attività. Questa restrizione si applica in genere anche ad altri provider di archiviazione.

Il diagramma seguente illustra un hub attività per ogni app per le funzioni in account di archiviazione di Azure condivisi e dedicati.

Diagramma che illustra gli account di archiviazione condivisi e dedicati.

Nota

L'eccezione alla regola di condivisione dell'hub attività è se si configura l'app per il ripristino di emergenza a livello di area. Per altre informazioni, vedere l'articolo sul ripristino di emergenza e sulla distribuzione geografica .

Ispezione del contenuto

Esistono diversi modi comuni per esaminare il contenuto di un hub attività:

  1. All'interno di un'app per le funzioni, l'oggetto client fornisce metodi per eseguire query nell'archivio di istanze. Per altre informazioni sui tipi di query supportate, vedere l'articolo Gestione istanze .
  2. Analogamente, l'API HTTP offre richieste REST per eseguire query sullo stato delle orchestrazioni e delle entità. Per altri dettagli, vedere Le informazioni di riferimento sulle API HTTP .
  3. Lo strumento monitoraggio Durable Functions consente di esaminare gli hub attività e offre varie opzioni per la visualizzazione visiva.

Per alcuni dei provider di archiviazione, è anche possibile esaminare l'hub attività passando direttamente all'archiviazione sottostante:

  • Se si usa il provider di archiviazione di Azure, gli stati dell'istanza vengono archiviati nella tabella dell'istanza e nella tabella di cronologia che è possibile esaminare usando strumenti come Azure Storage Explorer.
  • Se si usa il provider di archiviazione MSSQL, è possibile usare query e strumenti SQL per esaminare il contenuto dell'hub attività all'interno del database.

Rappresentazione nell'archiviazione

Ogni provider di archiviazione usa un'organizzazione interna diversa per rappresentare gli hub attività nell'archiviazione. La comprensione di questa organizzazione, anche se non necessaria, può essere utile durante la risoluzione dei problemi di un'app per le funzioni o quando si tenta di garantire obiettivi di prestazioni, scalabilità o costi. Viene quindi brevemente spiegato, per ogni provider di archiviazione, il modo in cui i dati sono organizzati nell'archiviazione. Per altre informazioni sulle varie opzioni del provider di archiviazione e sul relativo confronto, vedere i provider di archiviazione Durable Functions.

Provider di Archiviazione di Azure

Il provider di Archiviazione di Azure rappresenta l'hub attività nell'archiviazione usando i componenti seguenti:

  • Due tabelle di Azure archiviano gli stati dell'istanza.
  • Una coda di Azure archivia i messaggi di attività.
  • Una o più code di Azure archivia i messaggi di istanza. Ognuna di queste cosiddette code di controllo rappresenta una partizione assegnata a un subset di tutti i messaggi di istanza, in base all'hash dell'ID istanza.
  • Alcuni contenitori BLOB aggiuntivi usati per il lease di BLOB e/o messaggi di grandi dimensioni.

Ad esempio, un hub attività denominato xyz con PartitionCount = 4 contiene le code e le tabelle seguenti:

Diagramma che mostra l'organizzazione di archiviazione del provider di archiviazione del provider di archiviazione di Azure per 4 code di controllo.

Verranno quindi descritti questi componenti e il ruolo che svolgono in modo più dettagliato.

Per altre informazioni su come gli hub attività sono rappresentati dal provider di archiviazione di Azure, vedere la documentazione del provider di archiviazione di Azure .

Provider di archiviazione Netherite

Netherite partiziona tutto lo stato dell'hub attività in un numero specificato di partizioni. Nell'archiviazione vengono usate le risorse seguenti:

  • Un contenitore BLOB di Archiviazione di Azure che contiene tutti i BLOB, raggruppati per partizione.
  • Una tabella di Azure che contiene le metriche pubblicate sulle partizioni.
  • Spazio dei nomi Hub eventi di Azure per il recapito di messaggi tra partizioni.

Ad esempio, un hub attività denominato mytaskhub con PartitionCount = 32 è rappresentato nell'archiviazione come indicato di seguito:

Diagramma che mostra l'organizzazione di archiviazione Netherite per 32 partizioni.

Nota

Tutto lo stato dell'hub attività viene archiviato all'interno del x-storage contenitore BLOB. La DurableTaskPartitions tabella e lo spazio dei nomi EventHubs contengono dati ridondanti: se il contenuto viene perso, possono essere ripristinati automaticamente. Non è pertanto necessario configurare lo spazio dei nomi Hub eventi di Azure per conservare i messaggi oltre l'ora di scadenza predefinita.

Netherite usa un meccanismo di origine eventi, basato su un log e checkpoint, per rappresentare lo stato corrente di una partizione. Vengono usati sia BLOB in blocchi che BLOB di pagine. Non è possibile leggere questo formato direttamente dall'archiviazione, quindi l'app per le funzioni deve essere in esecuzione durante l'esecuzione di query sull'archivio di istanze.

Per altre informazioni sugli hub attività per il provider di archiviazione Netherite, vedere Informazioni sull'hub attività per il provider di archiviazione Netherite.

Provider di archiviazione MSSQL

Tutti i dati dell'hub attività vengono archiviati in un singolo database relazionale, usando diverse tabelle:

  • Le dt.Instances tabelle e dt.History archiviano gli stati dell'istanza.
  • La dt.NewEvents tabella archivia i messaggi di istanza.
  • La dt.NewTasks tabella archivia i messaggi di attività.

Diagramma che mostra l'organizzazione di archiviazione MSSQL.

Per consentire la coesistenza di più hub attività in modo indipendente nello stesso database, ogni tabella include una TaskHub colonna come parte della relativa chiave primaria. A differenza degli altri due provider, il provider MSSQL non ha un concetto di partizioni.

Per altre informazioni sugli hub attività per il provider di archiviazione MSSQL, vedere Informazioni sull'hub attività per il provider di archiviazione Microsoft SQL (MSSQL).

Nomi degli hub attività

Gli hub attività sono identificati da un nome che deve essere conforme a queste regole:

  • Contiene solo caratteri alfanumerici
  • Inizia con una lettera
  • Ha una lunghezza minima di 3 caratteri e una lunghezza massima di 45 caratteri

Il nome dell'hub attività viene dichiarato nel file host.json, come illustrato nell'esempio:

host.json (Funzioni 2.0)

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "MyTaskHub"
    }
  }
}

host.json (funzioni 1.x)

{
  "durableTask": {
    "hubName": "MyTaskHub"
  }
}

Gli hub attività possono essere configurati anche usando le impostazioni dell'app, come illustrato nel file di esempio seguente host.json :

host.json (Funzioni 1.0)

{
  "durableTask": {
    "hubName": "%MyTaskHub%"
  }
}

host.json (Funzioni 2.0)

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "%MyTaskHub%"
    }
  }
}

Il nome dell'hub attività verrà impostato in base al valore dell’impostazione dell’app MyTaskHub. La seguente impostazione local.settings.json spiega come configurare l’impostazione MyTaskHub su samplehubname:

{
  "IsEncrypted": false,
  "Values": {
    "MyTaskHub" : "samplehubname"
  }
}

Nota

Quando si usano gli slot di distribuzione, è consigliabile configurare il nome dell'hub attività usando le impostazioni dell'app. Se si vuole assicurarsi che uno slot specifico usi sempre un particolare hub attività, usare le impostazioni dell'app "slot-sticky".

Oltre a host.json, i nomi dell'hub attività possono essere configurati anche nei metadati di associazione client di orchestrazione . Ciò è utile se è necessario accedere a orchestrazioni o entità che risiedono in un'app per le funzioni separata. Il codice seguente illustra come scrivere una funzione che usa l'associazione client di orchestrazione per lavorare con un hub attività configurato come impostazione dell'app:

[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
    [DurableClient(TaskHub = "%MyTaskHub%")] IDurableOrchestrationClient starter,
    string functionName,
    ILogger log)
{
    // Function input comes from the request content.
    object eventData = await req.Content.ReadAsAsync<object>();
    string instanceId = await starter.StartNewAsync(functionName, eventData);

    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

    return starter.CreateCheckStatusResponse(req, instanceId);
}

Nota

L'esempio precedente è per Durable Functions 2.x. Per Durable Functions 1.x, è necessario usare DurableOrchestrationContext anziché IDurableOrchestrationContext. Per altre informazioni sulle differenze tra le versioni, vedere l'articolo Durable Functions versioni.

Nota

La configurazione dei nomi dell'hub attività nei metadati di associazione client è necessaria solo quando si usa un'app per le funzioni per accedere alle orchestrazioni e alle entità in un'altra app per le funzioni. Se le funzioni client vengono definite nella stessa app per le funzioni delle orchestrazioni e delle entità, è consigliabile evitare di specificare i nomi dell'hub attività nei metadati di associazione. Per impostazione predefinita, tutte le associazioni client ottengono i metadati dell'hub attività dalle impostazioni host.json .

I nomi degli hub attività devono iniziare con una lettera e contenere solo lettere e numeri. Se non specificato, verrà usato un nome dell'hub attività predefinito, come illustrato nella tabella seguente:

Versione dell'estensione durevole Nome dell'hub attività predefinito
2.x Quando viene distribuito in Azure, il nome dell'hub attività deriva dal nome dell'app per le funzioni. Quando si esegue all'esterno di Azure, il nome dell'hub attività predefinito è TestHubName.
1.x Il nome dell'hub attività predefinito per tutti gli ambienti è DurableFunctionsHub.

Per altre informazioni sulle differenze tra le versioni dell'estensione, vedere l'articolo Durable Functions versioni.

Nota

Il nome è ciò che distingue un hub attività da un altro quando sono presenti più hub attività in un account di archiviazione condiviso. Se si dispone di più app per le funzioni che condividono lo stesso account di archiviazione condiviso, è necessario configurare in modo esplicito nomi diversi per ogni hub attività nei file host.json. In caso contrario, le app per più funzioni saranno in competizione tra loro per i messaggi, il che potrebbe causare un comportamento indefinito, con orchestrazioni che si rimangono in modo imprevisto nello stato Pending o Running.

Passaggi successivi