Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln hjälper dig att diagnostisera och åtgärda vanliga problem när du skapar program med bärbara Durable Task SDK:er. Hitta ditt scenario i följande lista och följ de länkade stegen för att diagnostisera och lösa problemet.
Vanliga scenarier
Anslutning och installation
- Emulatorn körs inte eller kan inte nås
- Anslutningssträngformatet är felaktigt
- Klienten eller arbetaren kan inte ansluta
- Aktivitetshubben finns inte
- Identitetsbaserade autentiseringsfel på Azure
Orkestreringar
- Orkestreringen har stannat kvar i vänteläge
- Orkestreringen har fastnat i tillståndet 'Running'
- Nondeterministisk orchestrator-kod
- Serialiserings- och deserialiseringsfel
Aktiviteter
gRPC
Loggning och diagnostik
Språkspecifik
- C#: Källgeneratorvarningar orsakar byggfel
- C#: Roslyn analyzer genererar foreach-loopar
- Java: Fel om nekad Gradle-behörighet
- Java: OrchestratorBlockedException
- Python: Omförsöksprincipen kräver max_retry_interval
- Python: NärAllTask-undantagsbeteende
Dessa SDK:er ansluter till Durable Task Scheduler serverdel och körs på valfri värdplattform, inklusive Azure Container Apps, Kubernetes och virtuella datorer.
Anmärkning
Den här guiden beskriver de bärbara SDK:erna för varaktiga uppgifter. Information om problem som är specifika för tjänsten Durable Task Scheduler finns i Felsöka durable task scheduler. Information om problem som är specifika för Durable Functions-tillägget finns i felsökningsguiden Durable Functions.
Tips/Råd
Instrumentpanelen för övervakning av Durable Task Scheduler är användbara för att granska orkestreringsstatus, se körhistorik och identifiera fel. Använd den tillsammans med den här guiden för att påskynda felsökningen.
Hitta problemet
| Felmeddelande eller symptom | Avsnitt |
|---|---|
connection refused eller failed to connect vid start |
Emulatorn körs inte eller kan inte nås |
| Analysfel i anslutningssträngen eller autentiseringsfel vid start | Anslutningssträngformatet är felaktigt |
| Arbetaren ansluter men orkestreringarna startar inte | Aktivitetshubben finns inte |
401 Unauthorized- eller identitets-/rollfel på Azure |
Identitetsbaserade autentiseringsfel på Azure |
| Orkestrering har fastnat i "Väntar" | Orkestreringen har fastnat i tillståndet "Väntande" |
| Orkestrering har fastnat i "Running" | Orkestreringen har fastnat i läget "Körs" |
| Uppspelningsfel, oändliga loopar eller oväntat beteende | Nondeterministisk orchestrator-kod |
| Typmatchningsfel eller JSON-serialiseringsfel | Serialiserings- och deserialiseringsfel |
activity not found |
Aktiviteten hittades inte |
RESOURCE_EXHAUSTED eller message too large |
gRPC-meddelandestorleksgränsen har överskridits |
CANCELLED: Cancelled on client under nedstängning |
Fel vid avbrytande av dataström under avstängning |
CS0419
/
VSTHRD105 varningar avbryter byggprocessen |
Källgeneratorvarningar orsakar byggfel (C#) |
OrchestratorBlockedException (Java) |
OrchestratorBlockedException (Java) |
Otydligt fel vid användning av retry_policy (Python) |
Retry-principen kräver max_retry_interval (Python) |
Problem med anslutning och installation
Emulatorn körs inte eller kan inte nås
Om appen misslyckas vid start med ett anslutningsfel som "anslutningen nekades" eller "misslyckades att ansluta" kontrollerar du att Durable Task Scheduler-emulatorn körs och är tillgänglig.
Kontrollera att docker-containern för emulatorn körs:
docker ps | grep durabletaskKontrollera att portmappningarna är korrekta. Emulatorn exponerar två portar:
- 8080 – gRPC-slutpunkt (används av din app)
- 8082 – Instrumentpanelsgränssnitt
Om du använder en anpassad portmappning uppdaterar du din reťazec pripojenia så att den matchar värdporten som mappas till containerporten
8080.Testa anslutningen till gRPC-slutpunkten:
curl -v http://localhost:8080En anslutningsavslag anger att containern inte körs eller att portmappningen är felaktig.
Anslutningssträngformatet är felaktigt
Anslutningssträngsfel är en vanlig orsak till startfel. Kontrollera att din reťazec pripojenia matchar det förväntade formatet.
Lokal utveckling (emulator):
Endpoint=http://localhost:8080;Authentication=None
Azure (hanterad identitet):
Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity
Azure (användartilldelad hanterad identitet):
Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity;ClientID=<client-id>
Vanliga misstag:
- Använda
httpsför den lokala emulatorn (emulatorn använderhttp) - Användning av
httpför Azure slutpunkter (Azure kräverhttps) - Utelämna parametern
Authentication - Använda instrumentpanelsporten (
8082) i stället för gRPC-porten (8080)
Klienten eller arbetaren kan inte ansluta
Kontrollera att klienten och arbetaren har konfigurerats med rätt anslutningssträng och uppgiftshubbens namn.
using Microsoft.DurableTask.Client.AzureManaged;
using Microsoft.DurableTask.Worker.AzureManaged;
var connectionString = "Endpoint=http://localhost:8080;Authentication=None";
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddDurableTaskWorker()
.AddTasks(registry =>
{
registry.AddOrchestrator<MyOrchestrator>();
registry.AddActivity<MyActivity>();
})
.UseDurableTaskScheduler(connectionString);
builder.Services.AddDurableTaskClient()
.UseDurableTaskScheduler(connectionString);
Aktivitetshubben finns inte
Om orkestreringarna inte startar eller om arbetaren ansluter men inte bearbetar arbetet kanske aktivitetshubben inte finns i schemaläggaren. Emulatorn skapar vanligtvis aktivitetshubbar automatiskt med hjälp av DTS_TASK_HUB_NAMES miljövariabeln.
Kontrollera att emulatorn startades med rätt namn på aktivitetshubben:
docker run -d -p 8080:8080 -p 8082:8082 \
-e DTS_TASK_HUB_NAMES="my-taskhub" \
mcr.microsoft.com/dts/dts-emulator:latest
För Azure-värdbaserade schemaläggare skapar du aktivitetshubben med hjälp av Azure CLI:
az durabletask taskhub create \
--resource-group <resource-group> \
--scheduler-name <scheduler-name> \
--name <taskhub-name>
Identitetsbaserade autentiseringsfel på Azure
Om appen körs lokalt men misslyckas när den distribueras till Azure är problemet sannolikt relaterat till autentisering:
- Kontrollera att den hanterade identiteten har tilldelats till din app (systemtilldelad eller användartilldelad).
- Kontrollera att identiteten har rollen Durable Task Data Contributor för schemaläggarens resurs eller specifik uppgiftshubb.
- Kontrollera att reťazec pripojenia använder rätt
Authenticationvärde (ManagedIdentity). I Python skickar du enDefaultAzureCredential()-instans som parameterntoken_credentiali stället för att använda en reťazec pripojenia. - För användartilldelade identiteter kontrollerar du att
ClientIDi reťazec pripojenia matchar identitetens klient-ID.
Detaljerade anvisningar finns i Konfigurera hanterad identitet för Durable Task Scheduler.
Orkestreringsproblem
Orkestreringen har fastnat i läget "Väntar"
En arbetsprocess i status "Väntar" anger att den har schemalagts men att en arbetare inte har hämtat upp den. Kontrollera följande:
- Arbetaren är igång. Kontrollera att arbetsprocessen körs och är ansluten till samma aktivitetshubb där orkestreringen schemalagts.
- Namnet på aktivitetshubben matchar. Kontrollera att både arbetaren och klienten refererar till samma namn på aktivitetshubben. Ett matchningsfel gör att arbetaren avsöker en annan aktivitetshubb.
- Orchestrator har registrerats. Den orkestreringsfunktion eller -klass som refereras vid schemaläggning måste registreras med arbetaren.
Kontrollera att orchestrator-klassen har registrerats med arbetaren under starten. Om du använder källgeneratorer ([DurableTask] attribut) är registreringen automatisk. Annars registrerar du dig manuellt:
builder.Services.AddDurableTaskWorker()
.AddTasks(registry =>
{
registry.AddOrchestrator<MyOrchestrator>();
registry.AddActivity<MyActivity>();
})
.UseDurableTaskScheduler(connectionString);
Orkestreringen har fastnat i tillståndet "Körs"
En orkestrering som fastnat i "Running" innebär vanligtvis att den väntar på en uppgift som inte är slutförd. Om du vill diagnostisera öppnar du instrumentpanelen Durable Task Scheduler och kontrollerar orkestreringens körningshistorik. Leta efter den senast slutförda händelsen – nästa händelse i sekvensen är den som blockerar.
Vanliga orsaker:
- Aktiviteten har inte registrerats. Orkestreringen anropar ett aktivitetsnamn som inte är registrerat hos arbetaren. Instrumentpanelen visar ett
TaskScheduled-händelse utan motsvarandeTaskCompleted. Kontrollera att aktivitetsnamnet matchar mellan orkestreringskoden och arbetsregistreringen (se Aktivitet hittades inte). - Väntar på en extern händelse. Orkestreringsanropen
waitForExternalEventoch händelsen har inte startats än. Instrumentpanelen visar att enEventRaisedhändelse förväntas men saknas. Kontrollera händelsenamnet och att avsändaren riktar in sig på rätt orkestreringsinstans-ID. - Väntar på en hållbar timer. Orkestreringen skapar en timer som inte har upphört att gälla än. Instrumentpanelen visar en
TimerCreatedhändelse. Vänta tills timern utlöses eller kontrollera om varaktigheten för timern är längre än förväntat. - Aktiviteten genererar ett ohanterat undantag. Instrumentpanelen visar en
TaskFailedhändelse. Kontrollera detaljinformationen om felet för undantagsmeddelandet och stackspårningen.
Nondeterministisk orchestrator-kod
Orchestrator-koden måste vara deterministisk. Nondeterministisk kod orsakar omspelsfel som resulterar i oväntat beteende, oändliga loopar eller fel. Använd inte aktuell tid, slumptal, GUID eller I/O (t.ex. HTTP-anrop) direkt i orchestrator-kod. Använd de sammanhangsbaserade alternativen eller delegera till aktiviteter.
// ❌ 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");
Serialiserings- och deserialiseringsfel
Serialiseringsfel uppstår när de typer som används för orkestreringsindata, utdata eller aktivitetsresultat inte matchar mellan anroparen och den uppringda. Dessa fel kan visas som oväntade null värden, JsonException eller typecast-fel i orkestreringshistoriken.
Så här diagnostiserar du:
- Öppna Durable Task Scheduler-instrumentpanelen och granska orkestreringshistoriken. Titta på fälten
InputochResultför aktiviteter som misslyckades. - Kontrollera att den typ som förväntas av orkestratorn matchar den typ som returneras av aktiviteten. Om aktiviteten till exempel returnerar en
stringmen orkestratorn förväntar sig enintmisslyckas deserialiseringen. - Sök efter typer som inte kan serialiseras. Anpassade typer som inte kan serialiseras till JSON (till exempel typer med cirkelreferenser eller ingen standardkonstruktor) misslyckas tyst eller utlöser undantag.
Känt problem (Java): Att skicka en String direkt till en aktivitet kan resultera i strängar med dubbla citattecken (till exempel "\"hello\"" i stället för "hello"). Det här beteendet är ett känt problem. Kasta resultatet explicit eller använd omslutningsobjekt.
Tips/Råd
Använd enkla datatyper (strängar, siffror, matriser och oformaterade objekt eller POJO/POCO/dataklasser) för orkestrering och aktivitetsindata och utdata. Undvik komplexa typer med anpassad serialiseringslogik.
Aktivitetsproblem
Aktiviteten hittades inte
Om en orkestrering misslyckas med felet "aktiviteten hittades inte" matchar inte aktivitetsnamnet som registrerats med arbetaren det namn som används i orkestreringskoden.
I .NET kan aktiviteter registreras med klassnamn eller med hjälp av attributet [DurableTask] med källgeneratorer. Kontrollera att aktivitetsklassen ingår i arbetsregistreringen:
builder.Services.AddDurableTaskWorker()
.AddTasks(registry =>
{
registry.AddActivity<SayHello>();
})
.UseDurableTaskScheduler(connectionString);
När du anropar aktiviteten från en orkestrerare, använd klassens namn:
string result = await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo");
Hantering av aktivitetsfel
När en aktivitet utlöser ett undantag får orkestratorn en TaskFailedException (eller språkmotsvarighet). Fånga det här undantaget och granska den inre felinformationen för att hitta rotorsaken. I C# använder du ex.FailureDetails för att komma åt feltypen och meddelandet och IsCausedBy<T>() för att söka efter specifika undantagstyper.
Detaljerade exempel på felhantering och återförsöksprinciper på varje språk finns i Felhantering och återförsök.
gRPC-problem
gRPC-meddelandestorleksgränsen har överskridits
Om du ser ett fel av typen RESOURCE_EXHAUSTED eller message too large överskrider en orkestrering eller aktivitetsindata/utdata gRPC:s standard maximala meddelandestorlek på 4 MB.
Åtgärder:
- Minska storleken på indata och utdata. Lagra stora nyttolaster i extern lagring, till exempel Azure Blob Storage, och skicka endast referenser.
- Dela upp stora förgreningens resultat i mindre batchar som bearbetas via underordnade orkestreringar.
Fel vid annullering av dataström under nedstängning
När du stoppar en arbetare kan det uppstå CANCELLED: Cancelled on client fel. Dessa fel är vanligtvis ofarliga och uppstår eftersom gRPC-strömmen mellan arbetaren och schemaläggaren stängs under avstängningen. SDK:erna .NET, Python och Java hanterar dessa fel internt.
I JavaScript kan SDK:t utlösas Stream error Error: 1 CANCELLED: Cancelled on client när du anropar worker.stop(). Det här felet är ett känt problem. Omge ett stoppanrop med en try-catch om felet påverkar din avstängningslogik.
try {
await worker.stop();
} catch (error) {
// Ignore stream cancellation errors during shutdown
if (!error.message.includes("CANCELLED")) {
throw error;
}
}
Loggning och diagnostik
Utförlig loggningskonfiguration
Öka loggverositeten för att få mer information om SDK-åtgärder, inklusive gRPC-kommunikation och orkestreringsreplikhändelser.
I din appsettings.json- eller loggningskonfigurationsfil:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.DurableTask": "Debug"
}
}
}
Använd replaysäkra loggare för att undvika dubbletter av loggposter vid orkestreringsuppspelning.
public override async Task<string> RunAsync(
TaskOrchestrationContext context, string input)
{
ILogger logger = context.CreateReplaySafeLogger<MyOrchestrator>();
logger.LogInformation("Processing input: {Input}", input);
// ...
}
Application Insights-integrering
För produktionsprogram konfigurerar du Application Insights för att samla in telemetri från ditt Durable Task SDK-program. Integreringsmetoden beror på din värdplattform:
| Värdplattform | Installationsanvisningar |
|---|---|
| Azure Container-applikationer | Övervaka loggar i Azure Container Apps med Log Analytics |
| Azure App-tjänst | Aktivera diagnostikloggning för appar i Azure App Service |
| Azure Kubernetes Service | Övervaka Azure Kubernetes Service |
Mer information om diagnostik finns i Diagnostik i Durable Task SDK:er.
Språkspecifika problem
C#
Källgeneratorvarningar orsakar byggfel
Om du använder <TreatWarningsAsErrors>true</TreatWarningsAsErrors> i projektet kan Durable Task källkodsgeneratorer generera varningar (CS0419, VSTHRD105) som kan orsaka att bygget misslyckas. Ignorera dessa specifika varningar:
<PropertyGroup>
<NoWarn>$(NoWarn);CS0419;VSTHRD105</NoWarn>
</PropertyGroup>
Det här kända problemet spåras på GitHub och åtgärdas i en kommande version.
Roslyn analyzer genererar foreach-loopar
Durable Task Roslyn-analysatorn kan utlösa en ArgumentNullException när orchestrator lambda-kod är placerad i en foreach slinga. Det här beteendet är ett känt problem som inte påverkar körningsbeteendet. Uppdatera till den senaste versionen av analyspaketet för att hämta korrigeringen.
Java
Fel: nekad Gradle-åtkomst
I macOS eller Linux kan körningen ./gradlew misslyckas med ett "åtkomst nekad"-fel. Åtgärda det här felet genom att göra filen körbar:
chmod +x gradlew
OrchestratorBlockedException
Det OrchestratorBlockedException inträffar när orchestrator-koden utför en blockerande operation som SDK identifierar som potentiellt icke-deterministisk. Det här undantaget är ett skydd för att förhindra att orchestrator-kod bryter mot orchestrator-kodbegränsningar.
Vanliga orsaker:
- Anropar ett blockerande externt API i orchestrator-kod.
- Använda
Thread.sleep()direkt istället förctx.createTimer(). - Utför fil- eller nätverks-I/O i orchestrator-kod.
Flytta alla blockerings- eller I/O-åtgärder till aktiviteter.
Python
Återförsöksprincipen kräver max_retry_interval
När du konfigurerar en retry_policy i Python genererar utelämnande av parametern max_retry_interval ett fel som inte tydligt anger orsaken. Ange max_retry_intervalalltid :
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
)
WhenAllTask-undantagsbeteende
När du använder when_all för att köra flera uppgifter parallellt, om en eller flera aktiviteter misslyckas, kanske undantagsbeteendet inte matchar förväntningarna. Endast det första undantaget utlöses och de återstående uppgiftsundantagen kan förloras. Granska enskilda aktivitetsresultat om du behöver fullständig felinformation:
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}")
Få support
För frågor och rapportering av buggar öppnar du ett problem i GitHub lagringsplatsen för relevant SDK. När du rapporterar en bugg ska du inkludera:
- Påverkade orkestreringsinstans-IDn
- Tidsintervall i UTC som visar problemet
- Programnamn och distributionsregion (om det är relevant)
- SDK-version och värdplattform
- Relevanta loggar eller felmeddelanden
| SDK | GitHub-lagringsplats |
|---|---|
| .NET | microsoft/durabletask-dotnet |
| Java | microsoft/durabletask-java |
| JavaScript | microsoft/durabletask-js |
| Python | microsoft/durabletask-python |