Condividi tramite


Guida alla risoluzione dei problemi Durable Functions

Durable Functions è un'estensione di Funzioni di Azure che consente di compilare orchestrazioni serverless usando codice ordinario. Per altre informazioni su Durable Functions, vedere la panoramica Durable Functions.

Questo articolo fornisce una guida per la risoluzione dei problemi di scenari comuni nelle app di Durable Functions.

Nota

I tecnici di supporto Microsoft sono disponibili per facilitare la diagnosi dei problemi con l'applicazione. Se non è possibile diagnosticare il problema usando questa guida, è possibile inviare un ticket di supporto accedendo al pannello Nuova richiesta di supporto nella sezione Supporto e risoluzione dei problemi dell'app per le funzioni nel portale di Azure.

Screenshot della pagina della richiesta di supporto nel portale di Azure.

Suggerimento

Quando si esegue il debug e la diagnosi dei problemi, è consigliabile iniziare assicurando che l'app usi la versione più recente dell'estensione Durable Functions. La maggior parte del tempo, l'uso della versione più recente riduce i problemi noti già segnalati da altri utenti. Per istruzioni su come aggiornare la versione dell'estensione, leggere l'articolo Aggiorna Durable Functions versione dell'estensione.

La scheda Diagnosticare e risolvere i problemi nella portale di Azure è una risorsa utile per monitorare e diagnosticare i possibili problemi correlati all'applicazione. Fornisce anche soluzioni potenziali ai problemi in base alla diagnosi. Per altre informazioni, vedere Diagnostica dell'app per le funzioni di Azure .

Se le risorse precedenti non hanno risolto il problema, le sezioni seguenti forniscono consigli per sintomi dell'applicazione specifici:

L'orchestrazione è bloccata nello Pending stato

Quando si avvia un'orchestrazione, un messaggio "start" viene scritto in una coda interna gestita dall'estensione Durable e lo stato dell'orchestrazione viene impostato su "In sospeso". Dopo aver selezionato e elaborato correttamente il messaggio di orchestrazione da un'istanza dell'app disponibile, lo stato passerà a "Esecuzione" (o a un altro stato non in sospeso).

Usare la procedura seguente per risolvere i problemi relativi alle istanze di orchestrazione che rimangono bloccate in modo indefinito nello stato "In sospeso".

  • Controllare le tracce di Durable Task Framework per avvisi o errori per l'ID dell'istanza di orchestrazione interessata. Una query di esempio è disponibile nella sezione Errori/avvisi di traccia.

  • Controllare le code di controllo di Archiviazione di Azure assegnate all'agente di orchestrazione bloccata per verificare se il relativo "messaggio iniziale" è ancora disponibile Per altre informazioni sulle code di controllo, vedere la documentazione della coda di controllo del provider di archiviazione di Azure.

  • Modificare la versione di configurazione della piattaforma dell'app su "64 Bit". A volte le orchestrazioni non iniziano perché l'app è in esaurimento di memoria. Il passaggio al processo a 64 bit consente all'app di allocare più memoria totale. Questo vale solo per servizio app piani Basic, Standard, Premium e Elastic Premium. I piani gratuito o a consumo non supportano processi a 64 bit.

L'orchestrazione inizia dopo un lungo ritardo

Normalmente, le orchestrazioni iniziano entro pochi secondi dopo la pianificazione. Tuttavia, esistono alcuni casi in cui le orchestrazioni potrebbero richiedere più tempo per iniziare. Per risolvere i problemi relativi alle orchestrazioni, seguire questa procedura per iniziare a eseguire più di pochi secondi.

L'orchestrazione non viene completata/è bloccata nello Running stato

Se un'orchestrazione rimane nello stato "Esecuzione" per un lungo periodo di tempo, in genere significa che è in attesa di un'attività a esecuzione prolungata pianificata per il completamento. Ad esempio, potrebbe essere in attesa di un'attività timer durevole, di un'attività attività o di un'attività evento esterna da completare. Tuttavia, se si osserva che le attività pianificate sono state completate correttamente, ma l'orchestrazione non esegue ancora lo stato di avanzamento, potrebbe verificarsi un problema che impedisce all'orchestrazione di procedere all'attività successiva. Spesso si fa riferimento a orchestrazioni in questo stato come "orchestrazioni bloccate".

Seguire questa procedura per risolvere i problemi di orchestrazione bloccati:

  • Provare a riavviare l'app per le funzioni. Questo passaggio può essere utile se l'orchestrazione viene bloccata a causa di un bug temporaneo o deadlock nell'app o nel codice di estensione.

  • Controllare le code di controllo dell'account di archiviazione di Azure per verificare se le code sono in continua crescita. Questa query KQL di messaggistica di Archiviazione di Azure consente di identificare i problemi relativi alla dequeuing dei messaggi di orchestrazione. Se il problema influisce solo su una singola coda di controllo, potrebbe indicare un problema presente solo in un'istanza dell'app specifica, in cui il ridimensionamento o il basso per spostare l'istanza di macchina virtuale non integra potrebbe essere utile.

  • Usare la query di Application Insights nella sezione Messaggistica di Archiviazione di Azure per filtrare il nome della coda come ID partizione e cercare eventuali problemi correlati alla partizione della coda di controllo.

  • Controllare le indicazioni riportate in Durable Functions Procedure consigliate e strumenti di diagnostica. Alcuni problemi possono essere causati da Durable Functions anti-pattern noti.

  • Controllare la documentazione Durable Functions Controllo delle versioni. Alcuni problemi possono essere causati da modifiche di rilievo alle istanze di orchestrazione in anteprima.

L'orchestrazione viene eseguita lentamente

L'elaborazione dei dati elevata, gli errori interni e le risorse di calcolo insufficienti possono causare l'esecuzione di orchestrazioni più lente rispetto alla normale. Usare la procedura seguente per risolvere i problemi di orchestrazione che richiedono più tempo del previsto per l'esecuzione:

  • Controllare le tracce di Durable Task Framework per avvisi o errori per l'ID dell'istanza di orchestrazione interessata. Una query di esempio è disponibile nella sezione Errori/avvisi di traccia.

  • Se l'app usa il modello in-process .NET, è consigliabile abilitare le sessioni estese. Le sessioni estese possono ridurre al minimo i carichi di cronologia, che possono rallentare l'elaborazione.

  • Verificare le prestazioni e i colli di bottiglia di scalabilità. Le prestazioni dell'applicazione dipendono da molti fattori. Ad esempio, l'utilizzo elevato della CPU o il consumo di memoria di grandi dimensioni può causare ritardi. Leggere Prestazioni e scalabilità in Durable Functions per indicazioni dettagliate.

Query di esempio

Questa sezione illustra come risolvere i problemi scrivendo query KQL personalizzate nell'istanza di applicazione Azure Insights configurata per l'app Funzioni di Azure.

Messaggistica di Archiviazione di Azure

Quando si usa il provider di archiviazione di Azure predefinito, tutto il comportamento Durable Functions è basato sui messaggi della coda di Archiviazione di Azure e tutti gli stati correlati a un'orchestrazione vengono archiviati nell'archiviazione tabelle e nell'archiviazione BLOB. Quando la traccia di Durable Task Framework è abilitata, tutte le interazioni di Archiviazione di Azure vengono registrate in Application Insights e questi dati sono importanti per il debug e i problemi di prestazioni.

A partire dalla versione 2.3.0 dell'estensione Durable Functions, è possibile disporre di questi log di Durable Task Framework pubblicati nell'istanza di Application Insights aggiornando la configurazione di registrazione nel file host.json. Per informazioni e istruzioni su come eseguire questa operazione, vedere l'articolo Di registrazione di Durable Task Framework .

La query seguente consiste nell'esaminare le interazioni di Archiviazione di Azure end-to-end per un'istanza di orchestrazione specifica. Modificare start e orchestrationInstanceID filtrare in base all'intervallo di tempo e all'ID istanza.

let start = datetime(XXXX-XX-XXTXX:XX:XX); // edit this 
let orchestrationInstanceID = "XXXXXXX"; //edit this
traces  
| where timestamp > start and timestamp < start + 1h 
| where customDimensions.Category == "DurableTask.AzureStorage" 
| extend taskName = customDimensions["EventName"]
| extend eventType = customDimensions["prop__EventType"] 
| extend extendedSession = customDimensions["prop__IsExtendedSession"]
| extend account = customDimensions["prop__Account"] 
| extend details = customDimensions["prop__Details"] 
| extend instanceId = customDimensions["prop__InstanceId"] 
| extend messageId = customDimensions["prop__MessageId"] 
| extend executionId = customDimensions["prop__ExecutionId"] 
| extend age = customDimensions["prop__Age"] 
| extend latencyMs = customDimensions["prop__LatencyMs"] 
| extend dequeueCount = customDimensions["prop__DequeueCount"] 
| extend partitionId = customDimensions["prop__PartitionId"] 
| extend eventCount = customDimensions["prop__TotalEventCount"] 
| extend taskHub = customDimensions["prop__TaskHub"] 
| extend pid = customDimensions["ProcessId"]
| extend appName = cloud_RoleName
| extend newEvents = customDimensions["prop__NewEvents"]
| where instanceId == orchestrationInstanceID
| sort by timestamp asc
| project timestamp, appName, severityLevel, pid, taskName, eventType, message, details, messageId, partitionId, instanceId, executionId, age, latencyMs, dequeueCount, eventCount, newEvents, taskHub, account, extendedSession, sdkVersion

Errori di traccia/avvisi

La query seguente cerca errori e avvisi per un'istanza di orchestrazione specificata. Sarà necessario specificare un valore per orchestrationInstanceID.

let orchestrationInstanceID = "XXXXXX"; // edit this
let start = datetime(XXXX-XX-XXTXX:XX:XX); 
traces  
| where timestamp > start and timestamp < start + 1h
| extend instanceId = iif(isnull(customDimensions["prop__InstanceId"] ) , customDimensions["prop__instanceId"], customDimensions["prop__InstanceId"] ) 
| extend logLevel = customDimensions["LogLevel"]
| extend functionName = customDimensions["prop__functionName"]
| extend status = customDimensions["prop__status"]
| extend details = customDimensions["prop__Details"] 
| extend reason = customDimensions["prop__reason"]
| where severityLevel > 1 // to see all logs of  severity level "Information" or greater.
| where instanceId == orchestrationInstanceID
| sort by timestamp asc 

Coda di controllo/log ID partizione

La query seguente cerca tutte le attività associate alla coda di controllo instanceId. È necessario specificare il valore per l'istanzaID in orchestrationInstanceID e l'ora di inizio della query in start.

let orchestrationInstanceID = "XXXXXX"; // edit this
let start = datetime(XXXX-XX-XXTXX:XX:XX); // edit this
traces  // determine control queue for this orchestrator
| where timestamp > start and timestamp < start + 1h 
| extend instanceId = customDimensions["prop__TargetInstanceId"] 
| extend partitionId = tostring(customDimensions["prop__PartitionId"])
| where partitionId contains "control" 
| where instanceId == orchestrationInstanceID
| join kind = rightsemi(
traces  
| where timestamp > start and timestamp < start + 1h 
| where customDimensions.Category == "DurableTask.AzureStorage" 
| extend taskName = customDimensions["EventName"]
| extend eventType = customDimensions["prop__EventType"] 
| extend extendedSession = customDimensions["prop__IsExtendedSession"]
| extend account = customDimensions["prop__Account"] 
| extend details = customDimensions["prop__Details"] 
| extend instanceId = customDimensions["prop__InstanceId"] 
| extend messageId = customDimensions["prop__MessageId"] 
| extend executionId = customDimensions["prop__ExecutionId"] 
| extend age = customDimensions["prop__Age"] 
| extend latencyMs = customDimensions["prop__LatencyMs"] 
| extend dequeueCount = customDimensions["prop__DequeueCount"] 
| extend partitionId = tostring(customDimensions["prop__PartitionId"])
| extend eventCount = customDimensions["prop__TotalEventCount"] 
| extend taskHub = customDimensions["prop__TaskHub"] 
| extend pid = customDimensions["ProcessId"]
| extend appName = cloud_RoleName
| extend newEvents = customDimensions["prop__NewEvents"]
) on partitionId
| sort by timestamp asc
| project timestamp, appName, severityLevel, pid, taskName, eventType, message, details, messageId, partitionId, instanceId, executionId, age, latencyMs, dequeueCount, eventCount, newEvents, taskHub, account, extendedSession, sdkVersion

Informazioni di riferimento sulla colonna di Application Insights

Di seguito è riportato un elenco delle colonne proiettate dalle query precedenti e dalle rispettive descrizioni.

Colonna Descrizione
pid ID processo dell'istanza dell'app per le funzioni. Ciò è utile per determinare se il processo è stato riciclato durante l'esecuzione di un'orchestrazione.
taskName Nome dell'evento registrato.
eventType Tipo di messaggio, che in genere rappresenta il lavoro eseguito da un agente di orchestrazione. Ecco un elenco completo dei relativi valori possibili e delle relative descrizioni.
extendedSession Valore booleano che indica se le sessioni estese sono abilitate.
account Account di archiviazione usato dall'app.
dettagli Informazioni aggiuntive su un evento specifico, se disponibile.
instanceId ID per un'istanza di orchestrazione o entità specificata.
messageId ID di archiviazione di Azure univoco per un messaggio di coda specificato. Questo valore viene visualizzato più comunemente negli eventi di traccia ReceivedMessage, ProcessingMessage ed Eliminazione diMessage. Si noti che non è presente negli eventi SendMessage perché l'ID messaggio viene generato da Archiviazione di Azure dopo aver inviato il messaggio.
executionId ID dell'esecuzione dell'agente di orchestrazione, che cambia ogni volta continue-as-new che viene richiamato.
age Numero di millisecondi da quando un messaggio è stato accodato. I numeri di grandi dimensioni indicano spesso problemi di prestazioni. Un'eccezione è il tipo di messaggio TimerFired, che può avere un valore di età elevato a seconda della durata del timer.
latenzaM Numero di millisecondi presi da un'operazione di archiviazione.
dequeueCount Numero di volte in cui un messaggio è stato dequeued. In circostanze normali, questo valore è sempre 1. Se è più di uno, potrebbe verificarsi un problema.
partitionId Nome della coda associata a questo log.
totalEventCount Numero di eventi di cronologia coinvolti nell'azione corrente.
taskHub Nome dell'hub attività.
newEvents Elenco delimitato da virgole degli eventi di cronologia scritti nella tabella Cronologia nell'archiviazione.