Durable Functions für zustandsbehaftete Workflows
Orchestrieren Sie lang laufende Workflows mit Orchestrator-Mustern von Durable Functions (Fan-out/Fan-in, Verkettung, Überwachung) und verstehen Sie, wie der Zustand als Checkpoint gespeichert wird.
Durable Functions für zustandsbehaftete Workflows ist eine kostenlose Cloud & IT Cert Prep-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Cloud & IT Cert Prep-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Cloud & IT Cert Prep-Kurs umfasst insgesamt 4 Lektionen.
Warum Durable Functions?
Reguläre Azure Functions sind zustandslos – jeder Aufruf wird unabhängig ausgeführt und hat keine Kenntnis vorheriger Aufrufe. Durable Functions erweitern Azure Functions um die Möglichkeit, zustandsbehaftete, lang laufende Workflows mit einfachem async/await-Code zu schreiben. Das Durable Task Framework speichert den Zustand nach jedem Schritt automatisch als Checkpoint in Azure Storage. Dadurch können Workflows Serverneustarts, Timeouts oder geplante Wartungsarbeiten überstehen und genau an der Stelle fortgesetzt werden, an der sie unterbrochen wurden.
Die drei Funktionstypen
Durable Functions führt drei Funktionstypen ein. Eine Orchestrator-Funktion koordiniert den gesamten Workflow – sie ruft Activity-Funktionen auf und wartet mit yield oder await auf Ergebnisse, ohne dabei tatsächlich einen Thread zu blockieren. Eine Activity-Funktion führt eine einzelne Arbeitseinheit aus (z. B. einen API-Aufruf oder das Schreiben in eine Datenbank) und ist der einzige Ort, an dem Seiteneffekte auftreten sollten. Eine Entity-Funktion verwaltet kleine Teile eines dauerhaften Zustands (z. B. Zähler oder Flags) über mehrere Aufrufe hinweg.
// Client function (HTTP trigger) — starts the orchestration
module.exports = async function (context, req) {
const client = df.getClient(context);
const orderId = req.body.orderId;
const instanceId = await client.startNew('OrderOrchestrator', undefined, { orderId });
return client.createCheckStatusResponse(context.bindingData.req, instanceId);
};Das Verkettungsmuster
Das Verkettungsmuster führt Activity-Funktionen nacheinander aus und übergibt die Ausgabe einer Funktion als Eingabe an die nächste. Die Orchestrator-Funktion wartet nacheinander auf jede Activity. Wenn eine Activity fehlschlägt, wird der Workflow angehalten und kann ab dem fehlgeschlagenen Schritt neu gestartet werden. Dies ist das einfachste Muster für Durable Functions und eignet sich für Workflows, bei denen jeder Schritt vom Ergebnis des vorherigen abhängt, etwa für Pipelines zur Auftragsverarbeitung.
// Orchestrator: chaining pattern
const df = require('durable-functions');
module.exports = df.orchestrator(function* (context) {
const orderId = context.df.getInput().orderId;
const validated = yield context.df.callActivity('ValidateOrder', orderId);
const charged = yield context.df.callActivity('ChargePayment', validated);
const shipped = yield context.df.callActivity('ShipOrder', charged);
return { status: 'shipped', trackingId: shipped.trackingId };
});Fan-Out-/Fan-In-Muster
Das Fan-Out-/Fan-In-Muster startet mehrere Activity-Funktionen parallel und wartet, bis alle abgeschlossen sind, bevor der Workflow fortgesetzt wird. Die Orchestrator-Funktion startet alle Tasks gleichzeitig mit callActivity, ohne auf sie zu warten, sammelt die Task-Objekte in einem Array und wartet anschließend mit Task.all(). Für unabhängige Arbeitselemente wie die Verarbeitung mehrerer Dateien, den Aufruf mehrerer APIs oder Batchvorgänge ist dies deutlich schneller als eine sequenzielle Verarbeitung.
// Orchestrator: fan-out / fan-in
module.exports = df.orchestrator(function* (context) {
const items = context.df.getInput().items;
// Fan-out: start all tasks in parallel
const tasks = items.map(item => context.df.callActivity('ProcessItem', item));
// Fan-in: wait for all tasks to complete
const results = yield context.df.Task.all(tasks);
return results;
});Das Überwachungsmuster
Das Überwachungsmuster fragt ein externes System in bestimmten Abständen ab, bis eine Bedingung erfüllt ist – ähnlich einer Abfrageschleife, aber vollständig dauerhaft. Die Orchestrator-Funktion ruft eine Activity auf, um den Status zu prüfen, wartet mit createTimer ein konfigurierbares Intervall und wiederholt den Vorgang anschließend. Da der Zustand zwischen den Abfragen in Storage als Checkpoint gespeichert wird, verbraucht die Orchestrator-Funktion während des Wartens keine Compute-Ressourcen. Dadurch ist dieser Ansatz wesentlich effizienter als ein timerbasierter Ansatz mit aktivem Warten.
// Orchestrator: monitor pattern (poll until job completes)
module.exports = df.orchestrator(function* (context) {
const jobId = context.df.getInput().jobId;
const expiry = new Date(context.df.currentUtcDateTime);
expiry.setHours(expiry.getHours() + 24); // 24-hour timeout
while (context.df.currentUtcDateTime < expiry) {
const status = yield context.df.callActivity('GetJobStatus', jobId);
if (status === 'completed') return { jobId, status };
if (status === 'failed') throw new Error('Job failed');
// Wait 30 seconds before next poll
const nextCheck = new Date(context.df.currentUtcDateTime);
nextCheck.setSeconds(nextCheck.getSeconds() + 30);
yield context.df.createTimer(nextCheck);
}
throw new Error('Workflow timed out');
});Muster für menschliche Interaktion
Das Muster für menschliche Interaktion pausiert eine Orchestrierung und wartet auf ein externes Ereignis, etwa die Genehmigung durch eine Führungskraft. Die Orchestrator-Funktion wartet mit waitForExternalEvent, was tagelang oder wochenlang möglich ist, ohne Compute-Ressourcen zu verbrauchen. Ein externes System (z. B. ein Link zur Genehmigung per E-Mail, eine mobile App oder ein Webhook) ruft die HTTP-API von Durable Functions auf, um das Ereignis auszulösen und die Orchestrierung fortzusetzen. Kombinieren Sie dies mit einem Timer, um bei ausbleibender Antwort automatisch ein Timeout und eine Eskalation auszulösen.
// Orchestrator: wait for human approval with timeout
module.exports = df.orchestrator(function* (context) {
const request = context.df.getInput();
yield context.df.callActivity('SendApprovalEmail', request);
const timeout = df.Task.createTimer(context, new Date(Date.now() + 48 * 3600 * 1000));
const approval = context.df.waitForExternalEvent('ApprovalResponse');
const winner = yield context.df.Task.any([approval, timeout]);
if (winner === approval) {
const approved = winner.result;
return approved ? 'Approved' : 'Rejected';
} else {
return 'Timed out — escalated';
}
});Einschränkungen für Orchestrator-Funktionen
Orchestrator-Funktionen unterliegen wichtigen Einschränkungen, da sie zur Wiederherstellung des Zustands möglicherweise mehrfach anhand des Verlaufs erneut abgespielt werden. Sie müssen deterministisch sein – verwenden Sie niemals Date.now() oder Math.random() und führen Sie keine direkten E/A-Aufrufe aus. Verwenden Sie stattdessen context.df.currentUtcDateTime für Zeitstempel und rufen Sie für sämtliche E/A-Operationen Activity-Funktionen auf. Protokollierung im Rumpf der Orchestrator-Funktion erzeugt während der erneuten Wiedergabe doppelte Protokolleinträge. Verwenden Sie daher stattdessen Activity-Funktionen für die Protokollierung.
// WRONG — non-deterministic, will cause replay bugs
module.exports = df.orchestrator(function* (context) {
const now = new Date(); // Don't use Date()
const rand = Math.random(); // Don't use Math.random()
const data = await fetch('/api'); // Don't make HTTP calls directly
});
// CORRECT
module.exports = df.orchestrator(function* (context) {
const now = context.df.currentUtcDateTime; // OK
const data = yield context.df.callActivity('FetchData', null); // OK
});Verwalten von Instanzen: Status und Beendigung
Jeder Orchestrierungslauf verfügt über eine eindeutige Instanz-ID, mit der Sie den Status abfragen, Ereignisse senden oder die Instanz beenden können. Die HTTP-Verwaltungs-API von Durable Functions stellt Endpunkte zum Überprüfen des Status (GET /instances/{id}), zum Senden von Ereignissen (POST /instances/{id}/raiseEvent/{name}) und zum Beenden (POST /instances/{id}/terminate) bereit. Verwenden Sie in Ihren Funktionen das Durable-Client-Binding, um programmgesteuert auf diese Vorgänge zuzugreifen.
// Client function: check orchestration status
module.exports = async function (context, req) {
const client = df.getClient(context);
const instanceId = req.params.instanceId;
const status = await client.getStatus(instanceId, true, true, true);
return {
status: 200,
body: {
instanceId,
runtimeStatus: status.runtimeStatus,
customStatus: status.customStatus,
output: status.output
}
};
};Storage-Backend und Leistung
Durable Functions speichert den Orchestrierungsverlauf, den Instanzzustand und Nachrichtenwarteschlangen zwischen Funktionen in einem Azure Storage Account (oder in Azure-SQL-/Netherite-Backends für höheren Durchsatz). Jeder Checkpoint schreibt Daten in Azure Table Storage und Azure Queue Storage. Für Szenarien mit hohem Durchsatz (tausende gleichzeitig ausgeführte Orchestrierungen) verwendet das Netherite-Storage-Backend Azure Event Hubs und erzielt dadurch eine deutlich bessere Leistung. Überwachen Sie die Länge der Orchestrierungswarteschlange, um Engpässe zu erkennen.
// host.json: configure the Durable Task storage provider
{
'version': '2.0',
'extensions': {
'durableTask': {
'hubName': 'MyTaskHub',
'storageProvider': {
'type': 'azure',
'connectionStringName': 'AzureWebJobsStorage',
'controlQueueBatchSize': 32,
'maxQueuePollingInterval': '00:00:02'
}
}
}
}Fehlerbehandlung und Wiederholungen
Activity-Funktionen können Ausnahmen auslösen, die als TaskFailedException an die Orchestrator-Funktion weitergegeben werden. Verwenden Sie in der Orchestrator-Funktion try-catch-Blöcke, um Fehler ordnungsgemäß zu behandeln. Für vorübergehende Fehler konfigurieren Sie mit callActivityWithRetry automatische Wiederholungen mit Backoff. Geben Sie dabei die maximale Anzahl der Versuche, das Intervall bis zum ersten Wiederholungsversuch und den Backoff-Koeffizienten an. Dies ist das empfohlene Muster für Activities, die externe APIs oder Datenbanken aufrufen.
// Orchestrator: retry an activity with exponential backoff
module.exports = df.orchestrator(function* (context) {
const retryOptions = new df.RetryOptions(
5000, // firstRetryIntervalInMilliseconds
3 // maxNumberOfAttempts
);
retryOptions.backoffCoefficient = 2; // 5s, 10s, 20s
try {
const result = yield context.df.callActivityWithRetry(
'CallExternalAPI',
retryOptions,
context.df.getInput()
);
return result;
} catch (e) {
yield context.df.callActivity('SendFailureAlert', e.message);
throw e;
}
});Durable Entities
Durable Entities (Entity-Funktionen) implementieren kleine Teile eines dauerhaften Zustands, auf die über eine Identität zugegriffen werden kann – ähnlich wie virtuelle Akteure. Eine Entity verfügt über eine ID und einen Zustand, der zwischen Aufrufen erhalten bleibt. Sie rufen Operationen für eine Entity aus einer Orchestrator-Funktion oder einem Client auf, und die Entity verarbeitet diese nacheinander (serialisiert). Häufige Anwendungsfälle sind Zähler, Genehmigungsautomaten, Rate Limiter und Warenkörbe – also alle Szenarien, die einen dauerhaften, aktualisierbaren Zustand ohne Datenbank benötigen.
// Counter entity function
const df = require('durable-functions');
module.exports = df.entity(function (context) {
let count = context.df.getState(() => 0);
const operation = context.df.operationName;
if (operation === 'add') count += context.df.getInput();
if (operation === 'reset') count = 0;
if (operation === 'get') context.df.return(count);
context.df.setState(count);
});
// From orchestrator, increment counter entity
// const entityId = new df.EntityId('Counter', 'myCounter');
// yield context.df.callEntity(entityId, 'add', 1);Schnelltest
Testen Sie Ihr Verständnis der Konzepte von Microsoft Azure Fundamentals (AZ-900) aus dieser Lektion.
Lektionszusammenfassung
In dieser Lektion haben Sie Folgendes gelernt: Durable Functions ermöglichen zustandsbehaftete, lang laufende Workflows, indem sie den Zustand der Orchestrator-Funktion in Azure Storage als Checkpoint speichern. Zu den wichtigsten Mustern gehören Verkettung, Fan-Out/Fan-In, Überwachung und menschliche Interaktion, und Orchestrator-Funktionen müssen deterministisch sein – sämtliche E/A-Operationen und nicht deterministischen Aufrufe müssen über Activity-Funktionen erfolgen. Als Nächstes beschäftigen wir uns mit Azure Logic Apps.
Häufig gestellte Fragen
Ist die Lektion „Durable Functions für zustandsbehaftete Workflows“ kostenlos?
Ja — der vollständige Text von „Durable Functions für zustandsbehaftete Workflows“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Cloud & IT Cert Prep-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Cloud & IT Cert Prep-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Durable Functions für zustandsbehaftete Workflows“?
Orchestrieren Sie lang laufende Workflows mit Orchestrator-Mustern von Durable Functions (Fan-out/Fan-in, Verkettung, Überwachung) und verstehen Sie, wie der Zustand als Checkpoint gespeichert wird. Du übst Cloud & IT Cert Prep mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Cloud & IT Cert Prep zu starten?
Keine Vorkenntnisse erforderlich. Cloud & IT Cert Prep auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Durable Functions für zustandsbehaftete Workflows“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Cloud & IT Cert Prep-Lektion Code schreiben und ausführen?
Ja. Jede Cloud & IT Cert Prep-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Trigger und Bindings von Azure Functions
- Durable Functions für zustandsbehaftete Workflows
- Azure Logic Apps
- Event Grid und ereignisgesteuerte Architektur