Behandlung allgemeiner Probleme mit dem SDK für dauerhafte Aufgaben

Dieser Artikel hilft Ihnen beim Diagnostizieren und Beheben häufiger Probleme beim Erstellen von Anwendungen mit den tragbaren SdKs für dauerhafte Aufgaben. Suchen Sie Ihr Szenario in der folgenden Liste, und führen Sie die verknüpften Schritte aus, um das Problem zu diagnostizieren und zu beheben.

Häufige Szenarien

Verbindung und Einrichtung

Orchestrierungen

Aktivitäten

gRPC

Protokollierung und Diagnose

Sprachspezifisch

Diese SDKs stellen eine Verbindung mit dem Durable Task Scheduler-Back-End her und werden auf jeder Hostingplattform ausgeführt, einschließlich Azure Container Apps, Kubernetes und VMs.

Hinweis

In diesem Leitfaden werden die tragbaren sdKs für dauerhafte Aufgaben behandelt. Probleme, die den Dienst für den dauerhaften Aufgabenplaner betreffen, finden Sie unter Problembehandlung für den dauerhaften Aufgabenplaner. Spezifische Probleme für die Durable Functions-Erweiterung finden Sie in Durable Functions Handbuch zur Problembehandlung.

Tipp

Das Überwachungsdashboard für dauerhafte Aufgabenplanung ist nützlich, um den Orchestrierungsstatus zu prüfen, den Ausführungsverlauf anzuzeigen und Fehler zu identifizieren. Verwenden Sie es zusammen mit diesem Handbuch, um die Problembehandlung zu beschleunigen.

Problem finden

Fehlermeldung oder Symptom Abschnitt
connection refused oder failed to connect beim Start Der Emulator wird nicht ausgeführt oder kann nicht erreichbar sein.
Fehler bei der Analyse von Verbindungszeichenfolgen oder Authentifizierungsfehlern beim Start Das Verbindungszeichenfolgenformat ist falsch.
Worker stellt eine Verbindung bereit, aber die Orchestrierung beginnt nicht. Der Aufgabenhub ist nicht vorhanden.
Identitäts- oder Rollenfehler in Azure Identity-basierte Authentifizierungsfehler bei Azure
Orchestrierung bleibt in "Ausstehend" hängen Die Orchestrierung bleibt im Status "Ausstehend" stecken
Die Orchestrierung befindet sich dauerhaft im Zustand "Laufen". Die Orchestrierung steckt im Zustand "Ausführen" fest
Wiedergabefehler, endlose Schleifen oder unerwartetes Verhalten Nicht deterministischer Orchestratorcode
Typenkonflikt oder JSON-Serialisierungsfehler Serialisierungs- und Deserialisierungsfehler
activity not found Aktivität nicht gefunden
RESOURCE_EXHAUSTED oder message too large gRPC-Nachrichtengrößenbeschränkung überschritten
CANCELLED: Cancelled on client während des Herunterfahrens Datenstromabbruchfehler beim Herunterfahren
CS0419 / VSTHRD105 Warnungen unterbrechen den Build Quellgeneratorwarnungen führen zu Build-Fehlern (C#)
OrchestratorBlockedException (Java) OrchestratorBlockedException (Java)
Nicht hilfreicher Fehler bei Verwendung von retry_policy (Python) Retry-Richtlinie erfordert max_retry_interval (Python)

Verbindungs- und Setupprobleme

Der Emulator wird nicht ausgeführt oder kann nicht erreichbar sein.

Wenn die App beim Start mit einem Verbindungsfehler wie "Verbindung verweigert" oder "Verbindung nicht verbunden" fehlschlägt, überprüfen Sie, ob der Emulator für dauerhafte Aufgabenplanung ausgeführt wird und darauf zugegriffen werden kann.

  1. Überprüfen Sie, ob der Docker-Emulatorcontainer ausgeführt wird:

    docker ps | grep durabletask
    
  2. Überprüfen Sie, ob die Portzuordnungen korrekt sind. Der Emulator macht zwei Ports verfügbar:

    • 8080 – gRPC-Endpunkt (verwendet von Ihrer App)
    • 8082 – Dashboard-Benutzeroberfläche

    Wenn Sie eine benutzerdefinierte Portzuordnung verwenden, aktualisieren Sie Ihre Verbindungszeichenfolge so, dass sie dem Hostport entspricht, der dem Containerport 8080 zugeordnet ist.

  3. Testen der Konnektivität mit dem gRPC-Endpunkt:

    curl -v http://localhost:8080
    

    Eine Verbindungsverweigerung weist darauf hin, dass der Container nicht läuft oder dass die Portzuordnung falsch ist.

Das Verbindungszeichenfolgenformat ist falsch.

Verbindungszeichenfolgenfehler sind eine häufige Ursache für Startfehler. Überprüfen Sie, ob Ihr Verbindungszeichenfolge dem erwarteten Format entspricht.

Lokale Entwicklung (Emulator):

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

Azure (verwaltete Identität):

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

Azure (vom Benutzer zugewiesene verwaltete Identität):

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

Häufige Fehler:

  • Verwenden https für den lokalen Emulator (der Emulator verwendet http)
  • Verwenden von http für Azure Endpunkte (Azure erfordert https)
  • Auslassen des Authentication Parameters
  • Verwenden des Dashboardports (8082) anstelle des gRPC-Ports (8080)

Client oder Worker kann keine Verbindung herstellen

Überprüfen Sie, ob der Client und der Worker mit dem richtigen Connection String konfiguriert sind und beachten Sie den korrekten Task-Hub-Namen.

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

Der Task-Hub existiert nicht.

Falls Ihre Orchestrierungen nicht starten oder der Worker zwar eine Verbindung herstellt, aber keine Arbeit verarbeitet, ist der Task-Hub möglicherweise nicht im Scheduler vorhanden. Der Emulator erstellt aufgabenhubs in der Regel automatisch mithilfe der DTS_TASK_HUB_NAMES Umgebungsvariable.

Überprüfen Sie, ob der Emulator mit dem richtigen Namen des Aufgabenhubs gestartet wurde:

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

Erstellen Sie für Azure gehostete Scheduler den Aufgabenhub mithilfe der Azure CLI:

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

Identitätsbasierte Authentifizierungsfehler bei Azure

Wenn Ihre App lokal ausgeführt wird, aber bei der Bereitstellung in Azure fehlschlägt, hängt das Problem wahrscheinlich mit der Authentifizierung zusammen:

  1. Überprüfen Sie, ob die verwaltete Identität Ihrer App zugewiesen ist (vom System zugewiesen oder vom Benutzer zugewiesen).
  2. Überprüfen Sie, ob die Identität über die Rolle Durable Task Data Contributor für die Scheduler-Ressource oder einen spezifischen Task-Hub verfügt.
  3. Stellen Sie sicher, dass der Verbindungszeichenfolge den richtigen wert Authentication (ManagedIdentity) verwendet. Übergeben Sie in Python eine Instanz DefaultAzureCredential() als Parameter token_credential anstatt eine Verbindungszeichenfolge zu verwenden.
  4. Überprüfen Sie bei von Benutzern zugewiesenen Identitäten, ob die ClientID im Verbindungszeichenfolge mit der Client-ID der Identität übereinstimmt.

Ausführliche Anweisungen finden Sie unter Verwalten Sie die Identität für den Dauerhaften Aufgabenplaner konfigurieren.

Orchestrierungsprobleme

Die Orchestrierung hängt im Zustand „Ausstehend“ fest.

Eine Orchestrierung mit dem Status „Ausstehend“ bedeutet, dass sie eingeplant wurde, aber noch kein Mitarbeiter sie übernommen hat. Überprüfen Sie die folgenden Elemente:

  • Der Worker wird ausgeführt. Stellen Sie sicher, dass der Workler-Prozess ausgeführt wird und mit demselben Aufgabenhub verbunden ist, in dem die Orchestrierung geplant wurde.
  • Der Aufgabenhub-Name stimmt überein. Überprüfen Sie, ob sowohl der Worker als auch der Client auf denselben Task Hub-Namen verweisen. Eine Abweichung führt dazu, dass der Worker einen anderen Aufgabenhub anfragt.
  • Orchestrator ist registriert. Die Orchestratorfunktion oder Klasse, auf die bei der Planung verwiesen wird, muss beim Worker registriert werden.

Überprüfen Sie, ob die Orchestratorklasse beim Startup beim Worker registriert ist. Wenn Sie Quellgeneratoren ([DurableTask] Attribut) verwenden, wird die Registrierung automatisch. Andernfalls können Sie sich manuell registrieren:

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

Die Orchestrierung hängt im Zustand "Läuft" fest.

Eine Orchestrierung, die im Status "Ausgeführt" hängen bleibt, bedeutet in der Regel, dass sie auf eine Aufgabe wartet, die nicht abgeschlossen ist. Öffnen Sie, um eine Diagnose zu stellen, das Dashboard "Durable Task Scheduler" und überprüfen Sie den Ausführungsverlauf der Orchestrierung. Suchen Sie nach dem letzten abgeschlossenen Ereignis – das nächste Ereignis in der Sequenz ist das, welches die Blockierung verursacht.

Häufige Ursachen:

  • Aktivität nicht registriert. Die Orchestrierung ruft eine Aktivitätsbezeichnung auf, die nicht für den Worker registriert ist. Das Dashboard zeigt ein TaskScheduled Ereignis ohne entsprechendes TaskCompleted. Überprüfen Sie, ob der Aktivitätsname zwischen Ihrem Orchestratorcode und der Workerregistrierung übereinstimmt (siehe Aktivität nicht gefunden).
  • Warten auf ein externes Ereignis. Die Orchestrierung ruft waitForExternalEvent auf, aber das Ereignis wurde noch nicht ausgelöst. Das Dashboard zeigt, dass ein EventRaised Ereignis erwartet wird, aber fehlt. Überprüfen Sie den Ereignisnamen und dass der Absender auf die richtige Orchestrierungsinstanz-ID abzielt.
  • Warten auf einen dauerhaften Timer. Die Orchestrierung erstellt einen Zeitgeber, der noch nicht abgelaufen ist. Das Dashboard zeigt ein TimerCreated Ereignis an. Warten Sie, bis der Timer ausgelöst wird, oder prüfen Sie, ob die Timerdauer länger als erwartet ist.
  • Aktivität löst eine unbehandelte Ausnahme aus. Das Dashboard zeigt ein TaskFailed Ereignis an. Überprüfen Sie die Fehlerdetails für die Ausnahmefehlernachricht und die Stapelverfolgung.

Nicht deterministischer Orchestratorcode

Orchestratorcode muss deterministisch sein. Nicht deterministischer Code verursacht Replay-Fehler, die zu unerwartetem Verhalten, unendlichen Schleifen oder Fehlern führen. Verwenden Sie keine aktuelle Zeit, Zufallszahlen, GUIDs oder E/A (z. B. HTTP-Aufrufe) direkt im Orchestratorcode. Verwenden Sie bereitgestellte Alternativen im Kontext oder delegieren Sie an Aktivitäten.

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

Serialisierungs- und Deserialisierungsfehler

Serialisierungsfehler treten auf, wenn die Typen, die für Orchestrierungseingaben, Orchestrierungsausgaben oder Aktivitätsergebnisse verwendet werden, nicht zwischen dem Anrufer und dem Angerufenen übereinstimmen. Diese Fehler können in Ihrem Orchestrierungsverlauf als unerwartete null Werte oder JsonExceptionUmwandlungsfehler auftreten.

Hinweise zur Diagnose:

  1. Öffnen Sie das Dashboard "Durable Task Scheduler" , und überprüfen Sie den Orchestrierungsverlauf. Sehen Sie sich die Input Felder und Result Felder für Aktivitäten an, die fehlgeschlagen sind.
  2. Überprüfen Sie, ob der vom Orchestrator erwartete Typ dem von der Aktivität zurückgegebenen Typ entspricht. Wenn beispielsweise die Aktivität einen string zurückgibt, jedoch der Orchestrator ein int erwartet, schlägt die Deserialisierung fehl.
  3. Überprüfen Sie, ob nicht serialisierbare Typen vorhanden sind. Benutzerdefinierte Typen, die nicht in JSON serialisiert werden können (z. B. Typen mit Zirkelbezügen oder kein Standardkonstruktor), schlagen im Hintergrund fehl oder lösen Ausnahmen aus.

Known-Problem (Java): Direktes Übergeben eines String an eine Aktivität kann zu doppelt zitierten Zeichenfolgen führen (z. B. "\"hello\"" anstelle von "hello"). Dieses Verhalten ist ein bekanntes Problem. Wandeln Sie das Ergebnis explizit um, oder verwenden Sie Wrapper-Objekte.

Tipp

Verwenden Sie einfache Datentypen (Zeichenfolgen, Zahlen, Arrays und einfache Objekte oder POJOs/POCOs/dataclasses) für Orchestrierungs- und Aktivitätseingaben und -ausgaben. Vermeiden Sie komplexe Typen mit benutzerdefinierter Serialisierungslogik.

Aktivitätsprobleme

Aktivität nicht gefunden

Wenn eine Orchestrierung mit einem Fehler "Aktivität nicht gefunden" fehlschlägt, stimmt der beim Worker registrierte Aktivitätsname nicht mit dem im Orchestrierungscode verwendeten Namen überein.

In .NET können Aktivitäten anhand des Klassennamens oder mithilfe des Attributs [DurableTask] mit Quellgeneratoren registriert werden. Überprüfen Sie, ob die Aktivitätsklasse in der Mitarbeiterregistrierung enthalten ist:

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

Verwenden Sie beim Aufrufen der Aktivität von einem Orchestrator den Klassennamen:

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

Behandlung von Aktivitätsfehlern

Wenn eine Aktivität eine Ausnahme auslöst, erhält der Orchestrator eine TaskFailedException (oder ein sprachliches Äquivalent). Erfassen Sie diese Ausnahme, und überprüfen Sie die inneren Fehlerdetails, um die Ursache zu finden. Verwenden Sie ex.FailureDetails in C#, um auf den Fehlertyp und die Meldung zuzugreifen, und IsCausedBy<T>(), um nach bestimmten Ausnahmetypen zu suchen.

Ausführliche Beispiele für die Fehlerbehandlung und wiederholungsrichtlinie in jeder Sprache finden Sie unter Fehlerbehandlung und Wiederholungsversuche.

gRPC-Probleme

gRPC-Nachrichtengrößenbeschränkung überschritten

Wenn ein RESOURCE_EXHAUSTED- oder message too large-Fehler angezeigt wird, überschreitet eine Orchestrierungs- oder Aktivitätseingabe/-ausgabe die standardmäßige maximale Nachrichtengröße von 4 MB.

Abhilfemaßnahmen:

  • Verringern Sie die Größe von Eingaben und Ausgaben. Speichern Sie große Nutzlasten im externen Speicher, z. B. Azure Blob Storage, und übergeben Sie nur Verweise.
  • Teilen Sie große Auffächern-Ergebnisse in kleinere Chargen auf, die durch Suborchestrierungen verarbeitet werden.

Fehler beim Abbruch von Datenströmen beim Herunterfahren

Beim Beenden eines Workers werden möglicherweise Fehler angezeigt CANCELLED: Cancelled on client . Diese Fehler sind in der Regel harmlos und treten auf, weil der gRPC-Stream zwischen Worker und Scheduler während des Herunterfahrens geschlossen wird. Die .NET, Python und Java SDKs behandeln diese Fehler intern.

In JavaScript kann das SDK beim Aufrufen Stream error Error: 1 CANCELLED: Cancelled on clientausgelöst werdenworker.stop(). Dieser Fehler ist ein bekanntes Problem. Schließen Sie den Stoppaufruf in einen try-catch-Block ein, falls der Fehler Ihre Herunterfahrlogik betrifft:

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

Protokollierung und Diagnose

Ausführliche Protokollierungskonfiguration

Erhöhen Sie die Ausführlichkeit der Protokollierung, um mehr Details über SDK-Operationen zu erhalten, einschließlich gRPC-Kommunikation und Orchestrierungs-Replay-Ereignissen.

In Ihrer appsettings.json Konfigurationsdatei oder Protokollierungsdatei:

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

Verwenden Sie wiedergabesichere Logger, um doppelte Protokolleinträge während der Orchestrierungswiedergabe zu vermeiden.

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

Application Insights-Integration

Konfigurieren Sie für Produktionsanwendungen Application Insights so, dass Telemetriedaten aus Ihrer Durable Task SDK-Anwendung gesammelt werden. Der Integrationsansatz hängt von Ihrer Hostingplattform ab:

Hostingplattform Setupanweisungen
Azure Container Apps – ein Dienst für containerbasierte Anwendungen Überwachen von Protokollen in Azure Container Apps mit Log Analytics
Azure App Service Aktivieren der Diagnoseprotokollierung für Apps in Azure App Service
Azure Kubernetes-Dienst Überwachen des Azure Kubernetes-Diensts

Weitere Informationen zur Diagnose finden Sie unter Diagnostics in Durable Task SDKs.

Sprachspezifische Probleme

C#

Warnungen beim Quellgenerator unterbrechen Builds

Wenn Sie <TreatWarningsAsErrors>true</TreatWarningsAsErrors> in Ihrem Projekt verwenden, können die Durable Task-Quellengeneratoren Warnungen (CS0419, VSTHRD105) erzeugen, die den Build unterbrechen. Unterdrücken Sie diese spezifischen Warnungen:

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

Dieses bekannte Problem wird auf GitHub nachverfolgt und wird in einer bevorstehenden Version behoben.

Roslyn Analyzer löst in foreach-Schleifen aus

Der Durable Task Roslyn Analyzer könnte eine Ausnahme auslösen, ArgumentNullExceptionwenn sich Orchestrator-Lambda-Code innerhalb einer foreach-Schleife befindet. Dieses Verhalten ist ein bekanntes Problem , das sich nicht auf das Laufzeitverhalten auswirkt. Aktualisieren Sie auf die neueste Analysepaketversion, um den Fix zu erhalten.

Java

Fehler bei verweigertem Gradle-Zugriff

Unter macOS oder Linux schlägt die Ausführung ./gradlew möglicherweise mit einem Fehler "Berechtigung verweigert" fehl. Beheben Sie diesen Fehler, indem Sie die Datei ausführbar machen.

chmod +x gradlew

OrchestratorBlockedException

Der OrchestratorBlockedException tritt auf, wenn der Orchestrator-Code eine Blockierungsoperation ausführt, die das SDK als potenziell nichtdeterministisch erkennt. Diese Ausnahme ist ein Schutz, um zu verhindern, dass Orchestratorcode-Codeeinschränkungen verletzt werden.

Häufige Ursachen:

  • Aufrufen einer blockierenden externen API im Orchestratorcode.
  • Direkte Verwendung Thread.sleep() anstelle von ctx.createTimer().
  • Ausführen von Datei- oder Netzwerk-E/A-Vorgängen im Orchestratorcode.

Verschieben Sie alle Blockierungs- oder E/A-Vorgänge in Aktivitäten.

Python

Die Wiederholungsrichtlinie erfordert ein max_retry_interval.

Wenn Sie einen retry_policy in Python konfigurieren, erzeugt das Weglassen des Parameters max_retry_interval einen Fehler, der nicht eindeutig auf die Ursache hinweist. Bitte immer max_retry_interval angeben:

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-Ausnahmeverhalten

Wenn Sie when_all verwenden, um mehrere Aufgaben parallel auszuführen, und eine oder mehrere Aufgaben fehlschlagen, kann das Fehlerverhalten möglicherweise nicht den Erwartungen entsprechen. Es wird nur die erste Ausnahme ausgelöst, die übrigen Aufgabenausnahmen könnten verloren gehen. Überprüfen Sie einzelne Vorgangsergebnisse, wenn Sie vollständige Fehlerinformationen benötigen:

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

Unterstützung erhalten

Wenn Sie Fragen und Fehler melden möchten, öffnen Sie ein Problem im GitHub Repository für das entsprechende SDK. Wenn Sie einen Fehler melden, schließen Sie Folgendes ein:

  • Betroffene Orchestrierungsinstanz-IDs
  • Zeitbereich in UTC, der das Problem anzeigt
  • Anwendungsname und Bereitstellungsregion (falls relevant)
  • SDK-Version und Hostingplattform
  • Relevante Protokolle oder Fehlermeldungen
SDK GitHub Repository
.NET microsoft/durabletask-dotnet
Java microsoft/durabletask-java
JavaScript microsoft/durabletask-js
Python microsoft/durabletask-python