Schnellstart: Erstellen einer App mit Java Durable Functions

Verwenden Sie Durable Functions, ein Feature von Azure Functions, um zustandsbehaftete Funktionen in einer serverlosen Umgebung zu schreiben. Durable Functions verwaltet Zustand, Prüfpunkte und Neustarts in Ihrer Anwendung.

In dieser Schnellstartanleitung erstellen und testen Sie eine Durable Functions-App in Java.

Eine einfache Durable Functions App verfügt über drei Funktionen:

  • Orchestrator-Funktion (Cities): Ein Workflow, der andere Funktionen koordiniert.
  • Aktivitätsfunktion (Capitalize): Eine Funktion, die der Orchestrator aufruft, um Arbeit auszuführen und einen Wert zurückzugeben.
  • Clientfunktion (StartOrchestration): Eine HTTP-ausgelöste Funktion, die den Orchestrator startet.

Diese Schnellstartanleitung bietet drei Setuppfade. Verwenden Sie die Auswahl oben auf der Seite, um Ihren bevorzugten Ansatz auszuwählen:

  • Manuelles Einrichten: Erstellen Sie jede Datei manuell, um die volle Kontrolle über die Projektstruktur zu haben.
  • Maven-Befehl: Verwenden Sie einen Maven-Archetyp, um das Projekt in einem Einzigen Befehl zu erstellen.
  • Visual Studio Code: Verwenden Sie die VS Code Azure Functions Erweiterung, um das Projekt über eine geführte Benutzeroberfläche zu generieren.

Voraussetzungen

Für die Durchführung dieses Schnellstarts benötigen Sie Folgendes:

  • Das Java Developer Kit Version 8 oder höher ist installiert.

  • Apache Maven Version 3.0 oder höher ist installiert.

  • Die neueste Version der Azure Functions Core Tools.

    Für Azure Functions 4.x ist Core Tools Version 4.0.4915 oder höher erforderlich.

  • Ein HTTP-Testtool , das Ihre Daten sicher hält. Weitere Informationen finden Sie unter HTTP-Testtools.

  • Visual Studio Code mit der erweiterung Azure Functions installiert (nur für den Visual Studio Code Setuppfad erforderlich).

  • Ein Azure-Abonnement. Um Durable Functions zu verwenden, müssen Sie über ein Azure Storage Konto verfügen.

Wenn Sie nicht über ein Azure-Konto verfügen, erstellen Sie ein kostenloses Konto , bevor Sie beginnen.

Hinzufügen erforderlicher Abhängigkeiten und Plug-Ins zu Ihrem Projekt

Fügen Sie ihrer pom.xml Datei den folgenden Code hinzu. Ersetzen Sie vor dem Kopieren your-unique-app-name durch einen global eindeutigen Funktions-App-Namen. Passen Sie region, javaVersion und resourceGroup an Ihre Umgebung an.

<properties>
  <azure.functions.maven.plugin.version>1.18.0</azure.functions.maven.plugin.version>
  <azure.functions.java.library.version>3.0.0</azure.functions.java.library.version>
  <durabletask.azure.functions>1.0.0</durabletask.azure.functions>
  <functionAppName>your-unique-app-name</functionAppName>
</properties>

<dependencies>
  <dependency>
    <groupId>com.microsoft.azure.functions</groupId>
    <artifactId>azure-functions-java-library</artifactId>
    <version>${azure.functions.java.library.version}</version>
  </dependency>
  <dependency>
    <groupId>com.microsoft</groupId>
    <artifactId>durabletask-azure-functions</artifactId>
    <version>${durabletask.azure.functions}</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
    </plugin>
    <plugin>
      <groupId>com.microsoft.azure</groupId>
      <artifactId>azure-functions-maven-plugin</artifactId>
      <version>${azure.functions.maven.plugin.version}</version>
      <configuration>
        <appName>${functionAppName}</appName>
        <resourceGroup>java-functions-group</resourceGroup>
        <appServicePlanName>java-functions-app-service-plan</appServicePlanName>
        <region>westus</region>
        <runtime>
          <os>windows</os>
          <javaVersion>11</javaVersion>
        </runtime>
        <appSettings>
          <property>
            <name>FUNCTIONS_EXTENSION_VERSION</name>
            <value>~4</value>
          </property>
        </appSettings>
      </configuration>
      <executions>
        <execution>
          <id>package-functions</id>
          <goals>
            <goal>package</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <artifactId>maven-clean-plugin</artifactId>
      <version>3.1.0</version>
    </plugin>
  </plugins>
</build>

Hinzufügen der erforderlichen JSON-Dateien

Fügen Sie ihrem Projektverzeichnis eine host.json-Datei hinzu. Sie sollte in etwa wie das folgende Beispiel aussehen:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.AzureStorage": "Warning",
      "DurableTask.Core": "Warning"
    }
  },
  "extensions": {
    "durableTask": {
      "hubName": "JavaTestHub"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

Hinweis

Durable Functions für Java erfordert Erweiterungspaket v4. Frühere Bündel werden nicht unterstützt. Weitere Informationen finden Sie in der Dokumentation zu Erweiterungspaketen.

Durable Functions benötigt einen Speicheranbieter, um den Laufzeitzustand zu speichern. Fügen Sie Ihrem Projektverzeichnis eine local.settings.json-Datei hinzu, um den Speicheranbieter zu konfigurieren. Zum Verwenden von Azure Storage als Anbieter legen Sie den Wert von AzureWebJobsStorage auf die Verbindungszeichenfolge Ihres Azure Storage-Kontos fest:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<your storage account connection string>",
    "FUNCTIONS_WORKER_RUNTIME": "java"
  }
}

Important

Die local.settings.json Datei kann geheime Schlüssel enthalten. Stellen Sie sicher, dass Sie es zu Ihrer .gitignore-Datei hinzufügen, um zu vermeiden, dass es ins Quellcode-Verwaltungssystem hochgeladen wird.

Erstellen Sie Ihre Orchestrator-, Aktivitäts- und Clientfunktionen von Durable Functions

Der folgende Beispielcode zeigt ein grundlegendes Beispiel für jeden Funktionstyp:

import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;
import java.util.*;

import com.microsoft.durabletask.*;
import com.microsoft.durabletask.azurefunctions.DurableActivityTrigger;
import com.microsoft.durabletask.azurefunctions.DurableClientContext;
import com.microsoft.durabletask.azurefunctions.DurableClientInput;
import com.microsoft.durabletask.azurefunctions.DurableOrchestrationTrigger;

public class DurableFunctionsSample {
    /**
     * This HTTP-triggered function starts the orchestration.
     */
    @FunctionName("StartOrchestration")
    public HttpResponseMessage startOrchestration(
            @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            @DurableClientInput(name = "durableContext") DurableClientContext durableContext,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        DurableTaskClient client = durableContext.getClient();
        String instanceId = client.scheduleNewOrchestrationInstance("Cities");
        context.getLogger().info("Created new Java orchestration with instance ID = " + instanceId);
        return durableContext.createCheckStatusResponse(request, instanceId);
    }

    /**
     * This is the orchestrator function, which can schedule activity functions, create durable timers,
     * or wait for external events in a way that's completely fault-tolerant.
     */
    @FunctionName("Cities")
    public String citiesOrchestrator(
            @DurableOrchestrationTrigger(name = "taskOrchestrationContext") TaskOrchestrationContext ctx) {
        String result = "";
        result += ctx.callActivity("Capitalize", "Tokyo", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "London", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "Seattle", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "Austin", String.class).await();
        return result;
    }

    /**
     * This is the activity function that is invoked by the orchestrator function.
     */
    @FunctionName("Capitalize")
    public String capitalize(@DurableActivityTrigger(name = "name") String name, final ExecutionContext context) {
        context.getLogger().info("Capitalizing: " + name);
        return name.toUpperCase();
    }
}

Erstellen eines lokalen Durable Functions Projekts mithilfe des Maven-Befehls

Führen Sie den folgenden Befehl aus, um ein Projekt zu generieren, das die grundlegenden Funktionen einer Durable Functions-App beinhaltet:

mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DarchetypeVersion=1.62 -Dtrigger=durablefunctions

Geben Sie nach entsprechender Aufforderung folgende Informationen ein:

Prompt Action
groupId Geben Sie com.function ein.
artifactId Geben Sie myDurableFunction ein.
Version Wählen Sie 1.0-SNAPSHOT aus.
Paket Geben Sie com.function ein.
Y Geben Sie Y ein und wählen Sie zum Bestätigen die EINGABETASTE aus.

Jetzt verfügen Sie über ein lokales Projekt mit den drei Funktionen, die sich in einer einfachen App für Durable Functions befinden. Der Archetyp fügt com.microsoft:durabletask-azure-functions automatisch als Abhängigkeit in Ihrer pom.xml-Datei hinzu.

Konfigurieren des Back-End-Speicheranbieters für Durable Functions

Durable Functions benötigt einen Speicheranbieter, um den Laufzeitzustand zu speichern. Sie können Azure Storage als Speicheranbieter in local.settings.json festlegen. Verwenden Sie die Verbindungszeichenfolge Ihres Azure-Speicherkontos als Wert für AzureWebJobsStorage wie in diesem Beispiel:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<your storage account connection string>",
    "FUNCTIONS_WORKER_RUNTIME": "java"
  }
}

Important

Die local.settings.json Datei kann geheime Schlüssel enthalten. Stellen Sie sicher, dass Sie es zu Ihrer .gitignore-Datei hinzufügen, um zu vermeiden, dass es im Quellcode-Repository gespeichert wird.

Erstellen Ihres lokalen Projekts

  1. Wählen Sie in Visual Studio Code F1 (oder STRG/CMD+UMSCHALT+P) aus, um die Befehlspalette zu öffnen. Geben Sie an der Eingabeaufforderung (>) Azure Functions: Neues Projekt erstellen ein und wählen Sie es aus.

    Screenshot des Befehls Azure Functions Neues Projekt erstellen in der Befehlspalette von Visual Studio Code.

  2. Wählen Sie Durchsuchen aus. Wechseln Sie im Dialogfeld Ordner auswählen zu einem Ordner, der für Ihr Projekt verwendet werden soll, und wählen Sie dann Auswählen aus.

  3. Geben Sie nach entsprechender Aufforderung folgende Informationen ein:

    Prompt Action
    Sprache auswählen Wählen Sie Java aus.
    Auswahl einer Version von Java Wählen Sie Java 8 oder höher aus. Wählen Sie die Java-Version aus, auf der Ihre Funktionen in Azure ausgeführt werden, und eine, die Sie lokal überprüft haben.
    Angeben einer Gruppen-ID Geben Sie com.function ein.
    Angeben einer Artefakt-ID Geben Sie myDurableFunction ein.
    Angeben einer Version Geben Sie 1.0-SNAPSHOT ein.
    Angeben eines Paketnamens Geben Sie com.function ein.
    Angeben eines App-Namens Geben Sie myDurableFunction ein.
    Auswahl des Buildtools für Java Projekt Wählen Sie Maven aus.
    Auswählen, wie Sie Ihr Projekt öffnen möchten Wählen Sie In neuem Fenster öffnen aus.

Sie verfügen jetzt über ein Projekt, das eine HTTP-Beispielfunktion hat. Sie können die generierte HTTP-Funktion entfernen, da Sie die Durable Functions im nächsten Schritt hinzufügen.

Hinzufügen von Funktionen zum Projekt

  1. Geben Sie in der Befehlspalette Azure Functions: Funktion erstellen ein und wählen Sie dann aus.

  2. Wählen Sie für Vorlagenfilter ändern und Alle aus.

  3. Geben Sie nach entsprechender Aufforderung folgende Informationen ein:

    Prompt Action
    Auswählen einer Vorlage für Ihre Funktion Wählen Sie DurableFunctionsOrchestration aus.
    Angeben eines Paketnamens Geben Sie com.function ein.
    Angeben eines Funktionsnamens Geben Sie DurableFunctionsOrchestrator ein.
  4. Wählen Sie im Dialogfeld Speicherkonto auswählen, um ein Speicherkonto einzurichten, und folgen Sie dann den Anweisungen.

Sie sollten nun die drei grundlegenden Funktionen für eine Durable Functions-App generiert haben.

Konfigurieren von pom.xml und host.json für Durable Functions

Fügen Sie Ihrer pom.xml Datei die folgende Abhängigkeit hinzu.

<dependency>
  <groupId>com.microsoft</groupId>
  <artifactId>durabletask-azure-functions</artifactId>
  <version>1.0.0</version>
</dependency>

Fügen Sie die extensions Eigenschaft zu Ihrer host.json Datei hinzu. Wenn die Datei bereits über andere Eigenschaften verfügt, führen Sie den extensions Block mit dem vorhandenen JSON zusammen:

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "JavaTestHub"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

Lokales Testen der Funktion

Azure Functions Core Tools bietet Ihnen die Möglichkeit, ein Azure Functions Projekt auf Ihrem lokalen Entwicklungscomputer auszuführen.

  1. Wenn Sie Visual Studio Code verwenden, öffnen Sie ein neues Terminalfenster, und führen Sie die folgenden Befehle aus, um das Projekt zu erstellen:

    mvn clean package
    

    Führen Sie dann die dauerhafte Funktion aus:

    mvn azure-functions:run
    
  2. Kopieren Sie im Panel „TERMINAL“ den URL-Endpunkt Ihrer über HTTP ausgelösten Funktion.

    Screenshot der Terminalausgabe mit der HTTP-Endpunkt-URL für die lokale Azure Functions runtime.

  3. Verwenden Sie Ihr HTTP-Testtool , um eine HTTP POST-Anforderung an den URL-Endpunkt zu senden.

    Die Antwort sollte ähnlich wie im folgenden Beispiel aussehen:

    {
        "id": "d1b33a60-333f-4d6e-9ade-17a7020562a9",
        "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9?code=ACCupah_QfGKo...",
        "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9/raiseEvent/{eventName}?code=ACCupah_QfGKo...",
        "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9?code=ACCupah_QfGKo...",
        "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9/terminate?reason={text}&code=ACCupah_QfGKo..."
    }
    

    Die Antwort ist das initiale Ergebnis der HTTP-Funktion. Sie teilt Ihnen mit, dass die dauerhafte Orchestrierung erfolgreich gestartet wurde. Das Endergebnis der Orchestrierung wird noch nicht angezeigt. Die Antwort enthält einige nützliche URLs. Fragen Sie zunächst den Status der Orchestrierung ab.

  4. Kopieren Sie den URL-Wert für statusQueryGetUri, fügen Sie diesen in die Adressleiste des Browsers ein, und führen Sie die Anforderung aus. Alternativ können Sie weiterhin das HTTP-Testtool verwenden, um die GET-Anforderung ausstellen zu können.

    Die Anforderung fragt die Orchestrierungsinstanz der Status ab. Es sollte angezeigt werden, dass die Instanz abgeschlossen ist und diese die Ausgaben oder Ergebnisse der Durable Function wie im folgenden Beispiel enthält:

    {
        "name": "Cities",
        "instanceId": "d1b33a60-333f-4d6e-9ade-17a7020562a9",
        "runtimeStatus": "Completed",
        "input": null,
        "customStatus": "",
        "output":"TOKYO, LONDON, SEATTLE, AUSTIN",
        "createdTime": "2022-12-12T05:00:02Z",
        "lastUpdatedTime": "2022-12-12T05:00:06Z"
    }