Schnellstart: Erstellen einer App mit Java Durable Functions

Verwenden Sie Durable Functions, ein Feature von Azure Functions, um zustandslose serverlose Workflows in Java zu schreiben. In dieser Schnellstartanleitung klonen und führen Sie eine Beispiel-App aus, die zwei gängige Orchestrierungsmuster veranschaulicht:

  • Funktionskette: Ruft Aktivitäten sequenziell auf (Tokio → Seattle → London).
  • Fan-out/Fan-In: Ruft Aktivitäten parallel in fünf Städten auf und aggregiert dann die Ergebnisse.

Am Ende haben Sie beide Orchestrierungen lokal mit dem Emulator " Durable Task Scheduler " ausgeführt und können ihren Status im Dashboard anzeigen.

  • Klonen Sie das Hello Cities-Beispielprojekt, und bereiten Sie es vor.
  • Richten Sie den Emulator "Durable Task Scheduler" und "Azurite" für die lokale Entwicklung ein.
  • Erstellen und ausführen Sie die Funktions-App, und lösen Sie beide Orchestrierungen aus.
  • Überprüfen Sie den Orchestrierungsstatus und die Ausgabe im Durable Task Scheduler-Dashboard.

Voraussetzungen

Einrichten des Emulators "Durable Task Scheduler"

Der Emulator Durable Task Scheduler stellt eine lokale Entwicklungsumgebung bereit, sodass Sie Orchestrierungen ohne Azure Abonnement testen können. Der host für Java Functions erfordert außerdem Azurite für den lokalen Speicher.

Starten Sie beide Container:

docker run -d --name dtsemulator -p 8080:8080 -p 8082:8082 \
  mcr.microsoft.com/dts/dts-emulator:latest

docker run -d --name azurite -p 10000:10000 -p 10001:10001 -p 10002:10002 \
  mcr.microsoft.com/azure-storage/azurite

Tip

Sobald der Emulator ausgeführt wird, können Sie auf das Dashboard http://localhost:8082 "Durable Task Scheduler" zugreifen, um Orchestrierungen zu überwachen.

Ausführen des Schnellstartbeispiels

  1. Navigieren Sie zum Beispielverzeichnis "Hello Cities":

    cd samples/durable-functions/java/HelloCities
    
  2. Stellen Sie sicher, dass die local.settings.json Datei die folgende Konfiguration enthält:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "java",
        "DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None"
      }
    }
    
  3. Erstellen Sie das Projekt:

    mvn clean package
    
  4. Starten Sie die Funktions-App:

    mvn azure-functions:run
    
  5. Starten Sie in einem separaten Terminal die Orchestrierung der Verkettung von Funktionen:

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/StartChaining
    $response
    

    Die Antwort enthält Status-URLs für die Orchestrierungsinstanz. Kopieren Sie den statusQueryGetUri Wert, und führen Sie ihn aus, um das Ergebnis zu überprüfen:

    Invoke-RestMethod -Uri $response.statusQueryGetUri
    
  6. Auslösen der Fanout-/Fan-In-Orchestrierung :

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/StartFanOutFanIn
    Invoke-RestMethod -Uri $response.statusQueryGetUri
    

Erwartete Ausgabe

Die POST-Anforderung gibt eine JSON-Antwort mit Status-URLs zurück. Zum Beispiel:

{
  "id": "<instanceId>",
  "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/<instanceId>?code=...",
  "sendEventPostUri": "...",
  "terminatePostUri": "...",
  "purgeHistoryDeleteUri": "..."
}

Wenn Sie statusQueryGetUri abfragen und der runtimeStatus der Orchestrierung Completed ist, finden Sie die Begrüßungsergebnisse im Feld output. Die Verkettungs-Orchestrierung gibt Folgendes zurück:

{
  "name": "ChainingOrchestration",
  "runtimeStatus": "Completed",
  "output": "Hello Tokyo! Hello Seattle! Hello London!"
}

Die Fan-out/Fan-in-Orchestrierung liefert Folgendes zurück:

{
  "name": "FanOutFanInOrchestration",
  "runtimeStatus": "Completed",
  "output": ["Hello Tokyo!", "Hello Seattle!", "Hello London!", "Hello Paris!", "Hello Berlin!"]
}

Tip

Wenn runtimeStatusRunning oder Pending anzeigt, warten Sie kurz und fragen Sie statusQueryGetUri erneut ab.

Öffnen Sie das Durable Task Scheduler-Dashboard unter http://localhost:8082, um den Orchestrierungsstatus und den Ausführungsverlauf einzusehen.

Grundlegendes zum Code

Das Beispielprojekt in src/main/java/com/example/Functions.java enthält alle drei Funktionstypen, die für eine Durable Functions App erforderlich sind.

Aktivitätsfunktion

Die SayHello Aktivität nimmt einen Stadtnamen und gibt eine Begrüßung zurück:

@FunctionName("SayHello")
public String sayHello(
        @DurableActivityTrigger(name = "city") String city) {
    return "Hello " + city + "!";
}

Orchestratorfunktionen

Der Verkettungs-Orchestrator ruft sequenziell für drei Städte auf SayHello :

@FunctionName("ChainingOrchestration")
public String chainingOrchestration(
        @DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {

    String result = "";
    result += ctx.callActivity("SayHello", "Tokyo", String.class).await();
    result += " " + ctx.callActivity("SayHello", "Seattle", String.class).await();
    result += " " + ctx.callActivity("SayHello", "London", String.class).await();
    return result;
}

Der Fan-out/Fan-in-Orchestrator plant Aktivitäten parallel:

@FunctionName("FanOutFanInOrchestration")
public List<String> fanOutFanInOrchestration(
        @DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {

    String[] cities = {"Tokyo", "Seattle", "London", "Paris", "Berlin"};
    List<Task<String>> parallelTasks = new ArrayList<>();

    for (String city : cities) {
        parallelTasks.add(ctx.callActivity("SayHello", city, String.class));
    }

    List<String> results = new ArrayList<>();
    for (Task<String> task : parallelTasks) {
        results.add(task.await());
    }

    return results;
}

Clientfunktionen

HTTP-ausgelöste Clientfunktionen starten jede Orchestrierung:

@FunctionName("StartChaining")
public HttpResponseMessage startChaining(
        @HttpTrigger(name = "req", methods = {HttpMethod.POST},
            authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Void> request,
        @DurableClientInput(name = "durableContext") DurableClientContext durableContext) {

    DurableTaskClient client = durableContext.getClient();
    String instanceId = client.scheduleNewOrchestrationInstance("ChainingOrchestration");
    return durableContext.createCheckStatusResponse(request, instanceId);
}

Konfiguration

Im Beispiel wird der Emulator "Durable Task Scheduler" als Speicher-Back-End verwendet. Dies ist konfiguriert in host.json:

{
  "extensions": {
    "durableTask": {
      "hubName": "default",
      "storageProvider": {
        "type": "azureManaged",
        "connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
      }
    }
  }
}

Die Verbindungszeichenfolge des Emulators ist in local.settings.json festgelegt:

{
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "java",
    "DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None"
  }
}

Bereinigen von Ressourcen

Beenden Sie die Emulatorcontainer, wenn Sie fertig sind:

docker stop dtsemulator azurite && docker rm dtsemulator azurite

Nächste Schritte