Veelvoorkomende problemen met durable task SDK oplossen

Dit artikel helpt u bij het vaststellen en oplossen van veelvoorkomende problemen bij het bouwen van toepassingen met de draagbare Durable Task SDK's. Zoek uw scenario in de volgende lijst en volg de gekoppelde stappen om het probleem vast te stellen en op te lossen.

Algemene scenario's

Verbinding en installatie

Orchestrationen

activiteiten

gRPC

Logboekregistratie en diagnostische gegevens

Taalspecifiek

Deze SDK's maken verbinding met de back-end Durable Task Scheduler en worden uitgevoerd op elk hostingplatform, waaronder Azure Container Apps, Kubernetes en VM's.

Opmerking

In deze handleiding worden de draagbare Durable Task SDK's behandeld. Zie Problemen oplossen die specifiek zijn voor de Durable Task Scheduler-service. Zie Durable Functions gids voor probleemoplossing voor problemen die specifiek zijn voor de Durable Functions-extensie.

Aanbeveling

Het bewakingsdashboard van Durable Task Scheduler is handig voor het controleren van de indelingsstatus, het weergeven van de uitvoeringsgeschiedenis en het identificeren van fouten. Gebruik deze naast deze handleiding om het oplossen van problemen te versnellen.

Uw probleem vinden

Foutmelding of symptoom Afdeling
connection refused of failed to connect bij het opstarten Emulator wordt niet uitgevoerd of is niet bereikbaar
Fouten bij het parsen van verbindingsreeksen of verificatiefouten bij het opstarten De indeling van de verbindingsreeks is onjuist
Worker maakt verbinding, maar orkestraties worden niet gestart Taakhub bestaat niet
401 Unauthorized of identiteits-/rolfouten in Azure Authenticatiefouten op basis van identiteit in Azure
Orchestratie is vastgelopen in "In behandeling" Orchestratie is vastgelopen in de status "In behandeling"
Orchestratie vastgelopen in "Wordt uitgevoerd" Orchestratie is vastgelopen in de status 'Bezig met uitvoeren'
Herhalingsfouten, oneindige lussen of onverwacht gedrag Niet-deterministische orchestratorcode
Type komt niet overeen of JSON-serialisatiefouten Serialisatie- en deserialisatiefouten
activity not found Activiteit niet gevonden
RESOURCE_EXHAUSTED of message too large Maximale gRPC-berichtgrootte overschreden
CANCELLED: Cancelled on client tijdens afsluiten Streamannuleringsfouten tijdens afsluiten
CS0419 / VSTHRD105 waarschuwingen onderbreken bouwproces Source generator waarschuwingen zorgen voor build problemen (C#)
OrchestratorBlockedException (Java) OrchestratorBlockedException (Java)
Onbehulpzame foutmelding bij gebruik van retry_policy (Python) Beleid voor opnieuw proberen vereist max_retry_interval (Python)

Verbinding- en installatieproblemen

Emulator wordt niet uitgevoerd of is niet bereikbaar

Als uw app mislukt bij het opstarten met een verbindingsfout zoals 'verbinding geweigerd' of 'kan geen verbinding maken', controleert u of de Durable Task Scheduler-emulator wordt uitgevoerd en toegankelijk is.

  1. Controleer of de Docker-emulatorcontainer wordt uitgevoerd:

    docker ps | grep durabletask
    
  2. Controleer of de poorttoewijzingen juist zijn. De emulator bevat twee poorten:

    • 8080: gRPC-eindpunt (gebruikt door uw app)
    • 8082 - Dashboard UI

    Als u een aangepaste poorttoewijzing gebruikt, werkt u uw verbindingsreeks bij zodat deze overeenkomt met de hostpoort die is toegewezen aan de containerpoort 8080.

  3. Connectiviteit met het gRPC-eindpunt testen:

    curl -v http://localhost:8080
    

    Een verbindingsweigering geeft aan dat de container niet actief is of dat de poorttoewijzing onjuist is.

De indeling van de verbindingsreeks is onjuist

Verbindingsreeksfouten zijn een veelvoorkomende oorzaak van opstartfouten. Controleer of uw verbindingsreeks overeenkomt met de verwachte indeling.

Lokale ontwikkeling (emulator):

Endpoint=http://localhost:8080;Authentication=None

Azure (beheerde identiteit):

Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity

Azure (door de gebruiker toegewezen beheerde identiteit):

Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity;ClientID=<client-id>

Algemene fouten:

  • Gebruiken https voor de lokale emulator (de emulator gebruikt http)
  • Het gebruik van http voor Azure eindpunten (Azure vereist https)
  • De Authentication parameter weglaten
  • De dashboardpoort (8082) gebruiken in plaats van de gRPC-poort (8080)

Client of werker kan niet verbinding maken

Controleer of uw client en worker zijn geconfigureerd met de juiste verbindingsreeks en de naam van de taakhub.

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);

Taakhub bestaat niet

Als uw orchestraties niet worden gestart of als de worker verbinding maakt maar geen werk verwerkt, bestaat de taakhub mogelijk niet op de scheduler. De emulator maakt doorgaans automatisch taakhubs met behulp van de DTS_TASK_HUB_NAMES omgevingsvariabele.

Controleer of de emulator is gestart met de juiste naam van de taakhub:

docker run -d -p 8080:8080 -p 8082:8082 \
  -e DTS_TASK_HUB_NAMES="my-taskhub" \
  mcr.microsoft.com/dts/dts-emulator:latest

Voor Azure gehoste planners maakt u de taakhub met behulp van de Azure CLI:

az durabletask taskhub create \
  --resource-group <resource-group> \
  --scheduler-name <scheduler-name> \
  --name <taskhub-name>

Verificatiefouten op basis van identiteit op Azure

Als uw app lokaal wordt uitgevoerd maar mislukt wanneer deze wordt geïmplementeerd in Azure, heeft het probleem waarschijnlijk betrekking op verificatie:

  1. Controleer of de beheerde identiteit is toegewezen aan uw app (door het systeem toegewezen of door de gebruiker toegewezen).
  2. Controleer of de identiteit de rol Duurzame taakgegevensbijdrager heeft voor de scheduler-resource of specifieke taakhub.
  3. Zorg ervoor dat de verbindingsreeks de juiste Authentication waarde (ManagedIdentity) gebruikt. Geef in Python een DefaultAzureCredential()-exemplaar door als de parameter token_credential in plaats van een verbindingsreeks te gebruiken.
  4. Controleer voor door de gebruiker toegewezen identiteiten of de ClientID in de verbindingsreeks overeenkomt met de client-id van de identiteit.

Zie voor gedetailleerde instructies Beheerde identiteit configureren voor Durable Task Scheduler.

Indelingsproblemen

Orchestratie is vastgelopen in de status "In afwachting".

Een orchestratie met de status "In behandeling" geeft aan dat deze is gepland, maar dat een worker deze niet heeft opgepakt. Controleer de volgende items:

  • Worker wordt uitgevoerd. Zorg ervoor dat uw werkproces wordt uitgevoerd en verbonden is met dezelfde taakhub waar de indeling is gepland.
  • Naam van taakhub komt overeen. Controleer of de worker en client beide verwijzen naar dezelfde taakhubnaam. Een mismatch zorgt ervoor dat de werkkracht een andere taakhub opvraagt.
  • De Orchestrator is geregistreerd. De orchestratorfunctie of orchestratorklasse waarnaar wordt verwezen bij het plannen, moet worden geregistreerd bij de worker.

Controleer of de orchestratorklasse is geregistreerd bij de worker tijdens het starten. Als u brongeneratoren ([DurableTask] kenmerk) gebruikt, wordt de registratie automatisch uitgevoerd. Anders registreert u zich handmatig:

builder.Services.AddDurableTaskWorker()
    .AddTasks(registry =>
    {
        registry.AddOrchestrator<MyOrchestrator>();
        registry.AddActivity<MyActivity>();
    })
    .UseDurableTaskScheduler(connectionString);

Orchestratie zit vast in de status 'Wordt uitgevoerd'

Een indeling die is vastgelopen in Uitvoeren, betekent meestal dat er wordt gewacht op een taak die niet is voltooid. Als u een diagnose wilt uitvoeren, opent u het "Durable Task Scheduler dashboard" en inspecteert u de uitvoeringsgeschiedenis van de orchestratie. Zoek naar de laatst voltooide gebeurtenis — de volgende gebeurtenis in de reeks is degene die alles blokkeert.

Veelvoorkomende oorzaken:

  • Activiteit is niet geregistreerd. De orchestratie roept een activiteitsnaam aan die niet is geregistreerd bij de werker. Het dashboard toont een TaskScheduled gebeurtenis zonder bijbehorende TaskCompleted. Controleer of de naam van de activiteit overeenkomt tussen uw orchestratorcode en werkrolregistratie (zie Activiteit niet gevonden).
  • Wachten op een externe gebeurtenis. De orkestratieaanroepen waitForExternalEvent en de gebeurtenis wordt nog niet getriggerd. Het dashboard toont een EventRaised gebeurtenis die wordt verwacht, maar ontbreekt. Controleer de naam van het evenement en of de afzender de juiste instance-ID van het orkestratie-exemplaar gebruikt.
  • Wachten op een duurzame timer. De orkestratie creëert een timer die nog niet is verlopen. In het dashboard wordt een TimerCreated gebeurtenis weergegeven. Wacht tot de timer is geactiveerd of controleer of de duur van de timer langer is dan verwacht.
  • Activiteit genereert een onverwerkte uitzondering. In het dashboard wordt een TaskFailed gebeurtenis weergegeven. Controleer de foutdetails van het uitzonderingsbericht en de stacktrace.

Niet-deterministische orchestratorcode

Orchestrator-code moet deterministisch zijn. Niet-deterministische code veroorzaakt herhalingsfouten die leiden tot onverwacht gedrag, eindeloze lussen of fouten. Gebruik geen huidige tijd, willekeurige getallen, GUID's of I/O (zoals HTTP-aanroepen) rechtstreeks in orchestratorcode. Gebruik de contextgerelateerde alternatieven of delegeren aan activiteiten.

// ❌ 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");

Serialisatie- en deserialisatiefouten

Serialisatiefouten treden op wanneer de typen die worden gebruikt voor orchestratie-invoer, -uitvoer of activiteitsresultaten niet overeenkomen tussen de aanroeper en de aangeroepene. Deze fouten kunnen verschijnen als onverwachte null waarden, JsonException of type cast-fouten in uw orkestratiegeschiedenis.

Diagnoses uitvoeren:

  1. Open het Durable Task Scheduler dashboard en inspecteer de indelingsgeschiedenis. Bekijk de Input en Result velden voor activiteiten die zijn mislukt.
  2. Controleer of het type dat door de orchestrator wordt verwacht, overeenkomt met het type dat door de activiteit wordt geretourneerd. Bijvoorbeeld, als de activiteit een string retourneert maar de orchestrator een int verwacht, faalt de deserialisatie.
  3. Controleer op niet-serialiseerbare typen. Aangepaste typen die niet kunnen worden geserialiseerd naar JSON (bijvoorbeeld typen met kringverwijzingen of geen standaardconstructor) mislukken op de achtergrond of genereren uitzonderingen.

Known issue (Java): Het rechtstreeks doorgeven van een String aan een activiteit kan leiden tot tekenreeksen met dubbele aanhalingstekens (bijvoorbeeld "\"hello\"" in plaats van "hello"). Dit gedrag is een bekend probleem. Cast het resultaat expliciet of gebruik wrapper-objecten.

Aanbeveling

Gebruik eenvoudige gegevenstypen (tekenreeksen, getallen, matrices en gewone objecten of POJOs/POCOs/dataclasses) voor indeling en activiteitsinvoer en -uitvoer. Vermijd complexe typen met aangepaste serialisatielogica.

Activiteitsproblemen

Activiteit niet gevonden

Als een orkestratie mislukt met de fout 'activiteit niet gevonden', komt de naam van de activiteit die is geregistreerd bij de worker niet overeen met de naam die in de orkestratiecode wordt gebruikt.

In .NET kunnen activiteiten worden geregistreerd op klassenaam of met behulp van het kenmerk [DurableTask] met brongeneratoren. Controleer of de activiteitsklasse is opgenomen in de werkrolregistratie:

builder.Services.AddDurableTaskWorker()
    .AddTasks(registry =>
    {
        registry.AddActivity<SayHello>();
    })
    .UseDurableTaskScheduler(connectionString);

Wanneer u de activiteit aanroept vanuit een orchestrator, gebruikt u de klassenaam:

string result = await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo");

Verwerking van activiteitsfouten

Wanneer een activiteit een uitzondering genereert, ontvangt de orchestrator een TaskFailedException (of taalequivalent). Bekijk deze uitzondering en inspecteer de interne foutdetails om de hoofdoorzaak te vinden. Gebruik in C# ex.FailureDetails om toegang te krijgen tot het fouttype en bericht en IsCausedBy<T>() om te controleren op specifieke uitzonderingstypen.

Zie Foutafhandeling en nieuwe pogingen voor gedetailleerde voorbeelden van foutafhandeling en beleid voor opnieuw proberen in elke taal.

gRPC-problemen

gRPC-berichtgrootte limiet overschreden

Als u een RESOURCE_EXHAUSTED of message too large fout ziet, overschrijdt een orkestratie of activiteitsinvoer/-uitvoer de standaard gRPC maximale berichtgrootte van 4 MB.

Mitigerende maatregelen:

  • Verklein de grootte van invoer en uitvoer. Sla grote nettoladingen op in externe opslag, zoals Azure Blob Storage, en geef alleen verwijzingen door.
  • Breek grote fan-outresultaten op in kleinere batches die worden verwerkt via sub-orkestraties.

Stream-annuleringsfouten tijdens afsluiting

Wanneer u een werker stopt, ziet u mogelijk CANCELLED: Cancelled on client fouten. Deze fouten zijn doorgaans ongevaarlijk en treden op omdat de gRPC-verbinding tussen de werknemer en de planner wordt verbroken tijdens het afsluiten. De .NET, Python en Java SDK's verwerken deze fouten intern.

In JavaScript kan de SDK een fout genereren Stream error Error: 1 CANCELLED: Cancelled on client bij het aanroepen van worker.stop(). Deze fout is een bekend probleem. Verpak de stop-aanroep in een try-catch als de fout invloed heeft op je afsluitlogica.

try {
  await worker.stop();
} catch (error) {
  // Ignore stream cancellation errors during shutdown
  if (!error.message.includes("CANCELLED")) {
    throw error;
  }
}

Logboekregistratie en diagnostische gegevens

Uitgebreide configuratie voor logboekregistratie

Vergroot de uitgebreidheid van logboeken om meer informatie te krijgen over SDK-bewerkingen, waaronder gRPC-communicatie- en indelingsherhalingsgebeurtenissen.

In uw appsettings.json configuratiebestand of logboekregistratie:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.DurableTask": "Debug"
    }
  }
}

Gebruik herhalingsveilige loggers om dubbele logboekvermeldingen te voorkomen tijdens orchestratieherhaling.

public override async Task<string> RunAsync(
    TaskOrchestrationContext context, string input)
{
    ILogger logger = context.CreateReplaySafeLogger<MyOrchestrator>();
    logger.LogInformation("Processing input: {Input}", input);
    // ...
}

Application Insights-integratie

Voor productietoepassingen configureert u Application Insights om telemetrie te verzamelen van uw Durable Task SDK-toepassing. De integratiebenadering is afhankelijk van uw hostingplatform:

Hostingplatform Installatie-instructies
Azure Container Apps - een dienst van Microsoft waarmee je containers kunt uitvoeren en beheren in de cloud. Logboeken bewaken in Azure Container Apps met Log Analytics
Azure App Service Diagnostische logboekregistratie inschakelen voor apps in Azure App Service
Azure Kubernetes Service Azure Kubernetes Service monitoren

Zie Diagnostische gegevens in Durable Task SDK's voor meer informatie over diagnostische gegevens.

Taalspecifieke problemen

C#

Brongeneratorwaarschuwingen onderbreken builds

Als u <TreatWarningsAsErrors>true</TreatWarningsAsErrors> in uw project gebruikt, kunnen de Durable Task-brongeneratoren waarschuwingen (CS0419, VSTHRD105) produceren die uw build onderbreken. Deze specifieke waarschuwingen onderdrukken:

<PropertyGroup>
  <NoWarn>$(NoWarn);CS0419;VSTHRD105</NoWarn>
</PropertyGroup>

Dit bekende probleem wordt bijgehouden op GitHub en wordt opgelost in een toekomstige release.

Roslyn analysemodule werpt uitzonderingen in foreach-loops

De Durable Task Roslyn-analyzer kan een ArgumentNullException genereren wanneer orchestrator lambda-code zich in een foreach-lus bevindt. Dit gedrag is een bekend probleem dat geen invloed heeft op runtimegedrag. Werk het analyzer-pakket bij naar de nieuwste versie om de bugfix te ontvangen.

Java

Foutmelding: Gradle-toestemming geweigerd

Op macOS of Linux kan het uitvoeren van ./gradlew mislukken met de foutmelding "toestemming geweigerd". Los deze fout op door het uitvoerbare bestand te maken:

chmod +x gradlew

OrchestratorBlockedException

Dit OrchestratorBlockedException gebeurt wanneer orchestratorcode een blokkeringsbewerking uitvoert die door de SDK wordt gedetecteerd als mogelijk niet-deterministisch. Deze uitzondering is een beveiliging om te voorkomen dat orchestratorcode beperkingen van orchestratorcode schendt.

Veelvoorkomende oorzaken:

  • Een blokkerende externe API aanroepen in orchestratorcode.
  • Rechtstreeks Thread.sleep() gebruiken in plaats van ctx.createTimer().
  • Bestands- of netwerk-I/O uitvoeren in orchestratorcode.

Verplaats alle blokkerings- of I/O-bewerkingen naar activiteiten.

Python

Beleid voor opnieuw proberen vereist max_retry_interval

Wanneer u een retry_policy in Python configureert, wordt de parameter max_retry_interval weggelaten, waardoor de oorzaak niet duidelijk wordt aangegeven. Specificeer altijd 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
)

WhenAllTask-uitzonderingsgedrag

Wanneer u when_all meerdere taken parallel uitvoert als een of meer taken mislukken, komt het uitzonderingsgedrag mogelijk niet overeen met de verwachtingen. Alleen de eerste uitzondering wordt gegenereerd en de resterende taak-uitzonderingen kunnen verloren gaan. Controleer de resultaten van afzonderlijke taken als u volledige foutinformatie nodig hebt:

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}")

Ondersteuning vinden

Voor vragen en het melden van fouten opent u een probleem in de GitHub opslagplaats voor de relevante SDK. Wanneer u een fout rapporteert, neemt u het volgende op:

  • Betrokken instantie-id's voor indeling
  • Tijdsbereik in UTC waarin het probleem wordt weergegeven
  • Toepassingsnaam en implementatieregio (indien relevant)
  • SDK-versie en hostingplatform
  • Relevante logboeken of foutberichten
SDK GitHub-opslagplaats
.NET microsoft/durabletask-dotnet
Java microsoft/durabletask-java
JavaScript microsoft/durabletask-js
Python microsoft/durabletask-python