Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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
- Der Emulator wird nicht ausgeführt oder kann nicht erreichbar sein.
- Das Verbindungszeichenfolgenformat ist falsch.
- Client oder Worker kann keine Verbindung herstellen
- Der Aufgabenhub ist nicht vorhanden.
- Identity-basierte Authentifizierungsfehler bei Azure
Orchestrierungen
- Die Orchestrierung bleibt im Status "Ausstehend" hängen
- Die Orchestrierung bleibt im Zustand "Ausführen" hängen
- Nicht deterministischer Orchestratorcode
- Serialisierungs- und Deserialisierungsfehler
Aktivitäten
gRPC
Protokollierung und Diagnose
Sprachspezifisch
- C#: Warnungen beim Quellgenerator unterbrechen Builds
- C#: Roslyn Analyzer löst Foreachschleifen aus
- Java: Fehler bei verweigerter Gradle-Berechtigung
- Java: OrchestratorBlockedException
- Python: Die Wiederholungsrichtlinie erfordert max_retry_interval
- Python: WhenAllTask-Ausnahmeverhalten
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.
Überprüfen Sie, ob der Docker-Emulatorcontainer ausgeführt wird:
docker ps | grep durabletaskÜ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
8080zugeordnet ist.Testen der Konnektivität mit dem gRPC-Endpunkt:
curl -v http://localhost:8080Eine 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
httpsfür den lokalen Emulator (der Emulator verwendethttp) - Verwenden von
httpfür Azure Endpunkte (Azure erforderthttps) - Auslassen des
AuthenticationParameters - 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:
- Überprüfen Sie, ob die verwaltete Identität Ihrer App zugewiesen ist (vom System zugewiesen oder vom Benutzer zugewiesen).
- Ü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.
- Stellen Sie sicher, dass der Verbindungszeichenfolge den richtigen wert
Authentication(ManagedIdentity) verwendet. Übergeben Sie in Python eine InstanzDefaultAzureCredential()als Parametertoken_credentialanstatt eine Verbindungszeichenfolge zu verwenden. - Überprüfen Sie bei von Benutzern zugewiesenen Identitäten, ob die
ClientIDim 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
TaskScheduledEreignis ohne entsprechendesTaskCompleted. Ü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
waitForExternalEventauf, aber das Ereignis wurde noch nicht ausgelöst. Das Dashboard zeigt, dass einEventRaisedEreignis 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
TimerCreatedEreignis 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
TaskFailedEreignis 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:
- Öffnen Sie das Dashboard "Durable Task Scheduler" , und überprüfen Sie den Orchestrierungsverlauf. Sehen Sie sich die
InputFelder undResultFelder für Aktivitäten an, die fehlgeschlagen sind. - Überprüfen Sie, ob der vom Orchestrator erwartete Typ dem von der Aktivität zurückgegebenen Typ entspricht. Wenn beispielsweise die Aktivität einen
stringzurückgibt, jedoch der Orchestrator eininterwartet, schlägt die Deserialisierung fehl. - Ü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 vonctx.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 |