Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo consente di diagnosticare e risolvere i problemi comuni durante la compilazione di applicazioni con gli SDK di Durable Task portabili. Questi SDK si connettono al back-end Durable Task Scheduler ed eseguiti in qualsiasi piattaforma di hosting, tra cui App contenitore di Azure, Kubernetes e macchine virtuali. Per problemi specifici del servizio Durable Task Scheduler, vedere Risoluzione dei problemi del Durable Task Scheduler. Per i problemi di Durable Functions, vedere la guida alla risoluzione dei problemi di Durable Functions.
Suggerimento
Il dashboard di monitoraggio di Durable Task Scheduler è utile per esaminare lo stato dell'orchestrazione, visualizzare la cronologia di esecuzione e identificare gli errori. Usarlo insieme a questa guida per velocizzare la risoluzione dei problemi.
Trovare il problema
| Messaggio di errore o sintomo | Sezione |
|---|---|
connection refused o failed to connect all'avvio |
L'emulatore non è in esecuzione o non è raggiungibile |
| Errori di analisi della stringa di connessione o errori di autenticazione all'avvio | Il formato della stringa di connessione non è corretto |
| Il worker si connette ma le orchestrazioni non vengono avviate | L'hub attività non esiste |
401 Unauthorized o errori di identità/ruolo in Azure |
Fallimenti dell'autenticazione basata su identità in Azure |
| Orchestrazione bloccata in "In sospeso" | L'orchestrazione è bloccata nello stato "In sospeso" |
| Orchestrazione bloccata su "In esecuzione" | L'orchestrazione è bloccata nello stato "In esecuzione" |
| Errori di riproduzione, cicli infiniti o comportamento imprevisto | Codice dell'agente di orchestrazione non deterministico |
| Errori di serializzazione JSON o mancata corrispondenza del tipo | Errori di serializzazione e deserializzazione |
activity not found |
Attività non trovata |
RESOURCE_EXHAUSTED oppure message too large |
Limite di dimensioni dei messaggi gRPC superato |
CANCELLED: Cancelled on client durante l'arresto |
Errori di cancellazione del flusso durante il 'shutdown' |
CS0419
/
VSTHRD105 avvisi interrompono il build |
Gli avvisi del generatore di origine interrompono le compilazioni (C#) |
OrchestratorBlockedException (Java) |
OrchestratorBlockedException (Java) |
Errore non utile quando si usa retry_policy (Python) |
La politica di Retry richiede max_retry_interval (Python) |
Problemi di connessione e configurazione
L'emulatore non è in esecuzione o non è raggiungibile
Se la tua app non si avvia con un errore di connessione come "connessione rifiutata" o "non è riuscita a connettersi", verifica che l'emulatore del Durable Task Scheduler sia in esecuzione e accessibile.
Verificare che il contenitore Docker dell'emulatore sia in esecuzione:
docker ps | grep durabletaskVerificare le mappature corrette delle porte. L'emulatore espone due porte:
- 8080- endpoint gRPC (usato dall'app)
- 8082- Interfaccia utente del dashboard
Se si usa un mapping di porte personalizzato, aggiornare il stringa di connessione in modo che corrisponda alla porta host mappata alla porta del contenitore
8080.Testare la connettività all'endpoint gRPC:
curl -v http://localhost:8080Il rifiuto di connessione indica che il contenitore non è in esecuzione o che la mappatura delle porte non è corretta.
Il formato della stringa di connessione non è corretto
Gli errori delle stringhe di connessione sono una causa comune di errori di avvio. Verificare che il stringa di connessione corrisponda al formato previsto.
Sviluppo locale (emulatore):
Endpoint=http://localhost:8080;Authentication=None
Azure (identità gestita):
Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity
Azure (identità gestita assegnata dall'utente):
Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity;ClientID=<client-id>
Errori comuni:
- Uso
httpsdell'emulatore locale (l'emulatore usahttp) - L'uso di
httpper gli endpoint di Azure (Azure richiedehttps) - Omissione del
Authenticationparametro - Uso della porta del dashboard (
8082) anziché della porta gRPC (8080)
Il client o il lavoratore non riesce a connettersi
Se il client o il lavoratore non riesce a connettersi, verificare quanto segue:
- La stringa di connessione corrisponde al formato previsto visualizzato in Formato stringa di connessione non corretta.
- Il nome dell'hub attività è lo stesso sia per il client che per il worker.
-
Endpoint URL usa
httpper l'emulatore locale ehttpsper Azure.
Per esempi di configurazione completi in ogni lingua, vedere Creare un'app con GLI SDK per attività permanenti.
L'hub delle attività non esiste
Se le orchestrazioni non riescono ad avviarsi o il worker si connette ma non elabora il lavoro, è possibile che l'hub di attività non esista nell'utilità di pianificazione. L'emulatore in genere crea automaticamente hub di attività usando la variabile DTS_TASK_HUB_NAMES d'ambiente.
Verificare che l'emulatore sia stato avviato con il nome corretto dell'hub delle attività.
docker run -d -p 8080:8080 -p 8082:8082 \
-e DTS_TASK_HUB_NAMES="my-taskhub" \
mcr.microsoft.com/dts/dts-emulator:latest
Per le utilità di pianificazione ospitate su Azure, creare l'hub delle attività usando l'interfaccia interfaccia della riga di comando di Azure.
az durabletask taskhub create \
--resource-group <resource-group> \
--scheduler-name <scheduler-name> \
--name <taskhub-name>
Errori di autenticazione basati sull'identità in Azure
Se l'app viene eseguita in locale ma non riesce quando viene distribuita in Azure, è probabile che il problema sia correlato all'autenticazione:
- Verificare che l'identità gestita sia assegnata all'app (assegnata dal sistema o assegnata dall'utente).
- Verificare che l'identità disponga del ruolo Collaboratore dati delle attività durevoli nella risorsa dell'utilità di pianificazione o in un hub attività specifico.
- Assicurarsi che la stringa di connessione utilizzi il valore
Authenticationcorretto (ManagedIdentity). In Python, passare un'istanza diDefaultAzureCredential()come parametrotoken_credentialanziché usare una stringa di connessione. - Per le identità assegnate dall'utente, verificare che il
ClientIDnella stringa di connessione corrisponda all'ID client dell'identità.
Per istruzioni dettagliate, vedere Accesso basato su identità per Durable Task Scheduler.
Problemi di orchestrazione
L'orchestrazione è bloccata nello stato "In sospeso"
Un'orchestrazione nello stato "In sospeso" indica che è stata pianificata, ma un worker non l'ha prelevata. Controllare gli elementi seguenti:
- Worker in esecuzione. Verificare che il processo di lavoro sia in esecuzione e connesso allo stesso hub attività in cui è stata pianificata l'orchestrazione.
- Il nome dell'hub attività corrisponde. Verificare che il lavoratore e il client facciano entrambi riferimento allo stesso task hub name. Una mancata corrispondenza fa sì che il worker esegua il polling di un hub attività diverso.
- Orchestrator è registrato. La funzione o la classe dell'agente di orchestrazione a cui viene fatto riferimento durante la pianificazione deve essere registrata con il worker.
Verificare che la classe di orchestrazione sia registrata con il worker all'avvio. Se si usano generatori di origine ([DurableTask] attributo), la registrazione è automatica. In caso contrario, registrare manualmente:
builder.Services.AddDurableTaskWorker(builder =>
{
builder.AddTasks(tasks =>
{
tasks.AddOrchestrator<MyOrchestrator>();
tasks.AddActivity<MyActivity>();
});
});
L'orchestrazione è bloccata nello stato "In esecuzione"
Un'orchestrazione bloccata in "In esecuzione" significa in genere che è in attesa di un'attività che non è stata completata. Per effettuare la diagnosi, aprire il dashboard del Programma di Pianificazione Attività Permanenti ed esaminare la cronologia delle esecuzioni dell'orchestrazione. Cercare l'ultimo evento completato: l'evento successivo nella sequenza è quello che impedisce il progresso.
Cause comuni:
- Attività non registrata. L'orchestrazione chiama un nome di attività non registrato con il worker. Dashboard mostra un
TaskScheduledevento senza un corrispondenteTaskCompleted. Verificare che il nome dell'attività corrisponda tra il codice dell'orchestratore e la registrazione del lavoratore (vedere Attività non trovata). - In attesa di un evento esterno. L'orchestrazione chiama
waitForExternalEventma l'evento non è ancora stato attivato. Il dashboard mostra unEventRaisedevento previsto ma mancante. Verificare il nome dell'evento e assicurarsi che il mittente stia indirizzando correttamente l'ID istanza di orchestrazione. - In attesa di un timer durevole. L'orchestrazione crea un timer che non è ancora scaduto. Il dashboard mostra un
TimerCreatedevento. Attendere che il timer venga attivato o controllare se la durata del timer è più lunga del previsto. - L'attività genera un'eccezione non gestita. Il dashboard mostra un
TaskFailedevento. Controllare i dettagli dell'errore per il messaggio di eccezione e l'analisi dello stack.
Codice dell'agente di orchestrazione non deterministico
Il codice dell'agente di orchestrazione deve essere deterministico. Il codice non deterministico causa errori di riproduzione che causano comportamenti imprevisti, cicli infiniti o errori. Non usare l'ora corrente, i numeri casuali, i GUID o le operazioni di I/O (come le chiamate HTTP) direttamente nel codice dell'agente di orchestrazione. Usare le alternative fornite dal contesto o delegare alle attività.
// ❌ Wrong - non-deterministic
var now = DateTime.UtcNow;
var id = Guid.NewGuid();
var data = await httpClient.GetAsync("https://example.com/api");
// ✅ Correct - deterministic
var now = context.CurrentUtcDateTime;
var id = context.NewGuid();
var data = await context.CallActivityAsync<string>("FetchData");
Errori di serializzazione e deserializzazione
Gli errori di serializzazione si verificano quando i tipi usati per gli input di orchestrazione, gli output o i risultati dell'attività non corrispondono tra il chiamante e il chiamato. Questi errori possono apparire come valori imprevisti null, JsonException o errori di conversione di tipo nella cronologia dell'orchestrazione.
Come effettuare la diagnosi:
- Aprire il Dashboard del Pianificatore di Attività Durabile ed esaminare la cronologia dell'orchestrazione. Osserva i campi
Inpute le attivitàResultche hanno avuto esito negativo. - Verificare che il tipo previsto dall'orchestratore corrisponda al tipo restituito dall'attività. Ad esempio, se l'attività restituisce un
stringma l'agente di orchestrazione prevede unint, la deserializzazione fallisce. - Verificare la presenza di tipi non serializzabili. I tipi personalizzati che non possono essere serializzati in JSON (ad esempio, i tipi con riferimenti circolari o nessun costruttore predefinito) hanno esito negativo in modo invisibile all'utente o generano eccezioni.
Problema noto (Java): Il passaggio di un String direttamente a un'attività può comportare stringhe tra virgolette doppie (ad esempio, "\"hello\"" anziché "hello"). Questo comportamento è un problema noto. Effettua il cast del risultato in modo esplicito o utilizza oggetti wrapper.
Suggerimento
Usare tipi di dati semplici (stringhe, numeri, array e oggetti semplici o POJOs/POCOs/dataclasses) per l'orchestrazione e per gli input e output delle attività. Evitare tipi complessi con logica di serializzazione personalizzata.
Problemi di attività
Attività non trovata
Se un'orchestrazione non riesce con un errore "attività non trovata", il nome dell'attività registrato con il worker non corrisponde al nome usato nel codice di orchestrazione.
In .NET le attività possono essere registrate in base al nome della classe o usando l'attributo [DurableTask] con generatori di origine. Verificare che la classe di attività sia inclusa nella registrazione del lavoratore.
builder.Services.AddDurableTaskWorker(builder =>
{
builder.AddTasks(tasks =>
{
tasks.AddActivity<SayHello>();
});
});
Quando si chiama l'attività da un orchestratore, usare il nome della classe:
string result = await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo");
Gestione dei fallimenti delle attività
Quando un'attività genera un'eccezione, l'orchestratore riceve un TaskFailedException (o equivalente nella lingua). Intercettare questa eccezione ed esaminare i dettagli dell'errore interno per trovare la causa radice. In C# usare ex.FailureDetails per accedere al tipo di errore e al messaggio e IsCausedBy<T>() per verificare la presenza di tipi di eccezione specifici.
Per esempi dettagliati di criteri di gestione e ripetizione degli errori in ogni lingua, vedere Gestione degli errori e tentativi.
Problemi di gRPC
Limite di dimensioni dei messaggi gRPC superato
Se vedi un RESOURCE_EXHAUSTED o message too large errore, un input/output di orchestrazione o attività supera la dimensione massima predefinita di 4 MB del messaggio gRPC.
Mitigazioni:
- Ridurre le dimensioni degli input e degli output. Archiviare payload di grandi dimensioni nell'archiviazione esterna, ad esempio Archiviazione BLOB di Azure e passare solo riferimenti.
- Suddividere i risultati di fan-out di grandi dimensioni in batch più piccoli elaborati tramite orchestrazioni secondarie.
Errori di annullamento dello stream durante l'arresto
Quando si arresta un ruolo di lavoro, potrebbero verificarsi CANCELLED: Cancelled on client errori. Questi errori sono in genere innocui e si verificano perché il flusso gRPC tra il worker e l'utilità di pianificazione si chiude durante l'arresto. Gli SDK .NET, Python e Java gestiscono questi errori internamente.
In JavaScript, l'SDK potrebbe generare quando Stream error Error: 1 CANCELLED: Cancelled on client si chiama worker.stop(). Questo errore è un problema noto. Eseguire il wrapping della chiamata di arresto in un try-catch se l'errore influisce sulla logica di arresto:
try {
await worker.stop();
} catch (error) {
// Ignore stream cancellation errors during shutdown
if (!error.message.includes("CANCELLED")) {
throw error;
}
}
Registrazione e diagnostica
Configurazione della registrazione verbosa
Aumentare il livello di dettaglio del log per ottenere altri dettagli sulle operazioni dell'SDK, incluse le comunicazioni gRPC e gli eventi di riproduzione dell'orchestrazione.
Nel file di configurazione appsettings.json o di log:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.DurableTask": "Debug"
}
}
}
Usare logger sicuri per la riproduzione per evitare voci di log duplicate durante la riproduzione dell'orchestrazione:
public override async Task<string> RunAsync(
TaskOrchestrationContext context, string input)
{
ILogger logger = context.CreateReplaySafeLogger<MyOrchestrator>();
logger.LogInformation("Processing input: {Input}", input);
// ...
}
Integrazione con Application Insights
Per le applicazioni di produzione, configurare Application Insights per raccogliere dati di telemetria dall'applicazione Durable Task SDK. L'approccio di integrazione dipende dalla piattaforma di hosting:
| Piattaforma di hosting | Istruzioni di installazione |
|---|---|
| App contenitore di Azure | Monitorare i log nelle App contenitore di Azure con Log Analytics |
| Servizio app di Azure | Abilitare la registrazione diagnostica per le app in Servizio app di Azure |
| Servizio Azure Kubernetes | Monitorare il servizio Azure Kubernetes |
Per altre informazioni sulla diagnostica, vedere Diagnostics in Durable Task SDK .For more information about diagnostics, see Diagnostics in Durable Task SDK.
Problemi specifici della lingua
C#
Gli avvisi dei generatori di codice sorgente interrompono i build
Se si usa <TreatWarningsAsErrors>true</TreatWarningsAsErrors> nel progetto, i generatori di origini Durable Task potrebbero generare avvisi (CS0419, VSTHRD105) che interrompono la compilazione. Eliminare questi avvisi specifici:
<PropertyGroup>
<NoWarn>$(NoWarn);CS0419;VSTHRD105</NoWarn>
</PropertyGroup>
Questo problema noto è tracciato su GitHub e viene risolto in una versione futura.
L'analizzatore Roslyn genera cicli foreach
L'analizzatore Roslyn di Durable Task potrebbe generare un ArgumentNullException quando il codice lambda dell'agente di orchestrazione si trova all'interno di un ciclo foreach. Questo comportamento è un problema noto che non influisce sul comportamento di runtime. Eseguire l'aggiornamento alla versione più recente del pacchetto dell'analizzatore per ottenere la correzione.
Java
Errore permesso negato di Gradle
In macOS o Linux l'esecuzione ./gradlew potrebbe non riuscire con un errore di autorizzazione negata. Correggere questo errore rendendo eseguibile il file:
chmod +x gradlew
OrchestratorBlockedException
OrchestratorBlockedException si verifica quando il codice dell'agente di orchestrazione esegue un'operazione di blocco che l'SDK rileva come potenzialmente non deterministica. Questa eccezione è una protezione per impedire che il codice di orchestrazione violi i vincoli del codice dell'orchestratore.
Cause comuni:
- Chiamata di un'API esterna bloccante nel codice di orchestrazione.
- Uso
Thread.sleep()diretto anziché dictx.createTimer(). - Esecuzione di I/O di file o di rete nel codice dell'orchestratore.
Spostare tutte le operazioni di blocco o I/O nelle attività.
Python
La politica di ritentativo richiede max_retry_interval
Quando si configura un retry_policy in Python, omettendo il parametro max_retry_interval viene generato un errore che non indica chiaramente la causa. Specificare sempre max_retry_interval:
from datetime import timedelta
from durabletask import task
retry_policy = task.RetryPolicy(
max_number_of_attempts=3,
first_retry_interval=timedelta(seconds=5),
max_retry_interval=timedelta(minutes=1), # Required
)
Comportamento delle eccezioni di WhenAllTask
Quando si usa when_all per eseguire più attività in parallelo, se una o più attività hanno esito negativo, il comportamento dell'eccezione potrebbe non corrispondere alle aspettative. Viene generata solo la prima eccezione e le eccezioni dell'attività rimanenti potrebbero andare perse. Controllare i risultati delle singole attività se sono necessarie informazioni complete sull'errore:
tasks = [ctx.call_activity(process_item, input=item) for item in items]
try:
results = yield task.when_all(tasks)
except TaskFailedError as e:
# Only the first failure is raised
# Check individual tasks for comprehensive error handling
print(f"At least one task failed: {e}")
Ottenere supporto
Per domande e bug di segnalazione, aprire un problema nel repository GitHub per l'SDK pertinente. Quando si segnala un bug, includere:
- ID dell'istanza di orchestrazione interessata
- Intervallo di tempo in formato UTC che mostra il problema
- Nome dell'applicazione e area di distribuzione (se pertinente)
- Versione dell'SDK e piattaforma di hosting
- Log o messaggi di errore pertinenti
| SDK | GitHub repository (Repository GitHub) |
|---|---|
| .NET | microsoft/durabletask-dotnet |
| Java | microsoft/durabletask-java |
| JavaScript | microsoft/durabletask-js |
| Python | microsoft/durabletask-python |