你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用 Durable Functions(Azure Functions 的一项功能)在无服务器环境中编写有状态函数。 Durable Functions 管理应用程序中的状态、检查点和重启。
在本快速入门中,将在Java中创建和测试Durable Functions应用。
基本的 Durable Functions 应用包含三个函数:
-
业务流程编排函数 (
Cities):用于编排其他函数的工作流。 -
活动函数 (
Capitalize):业务流程协调程序调用执行工作并返回值的函数。 -
客户端函数 (
StartOrchestration):一个 HTTP 触发的函数,用于启动业务流程协调程序。
本快速入门提供三个设置路径。 使用页面顶部的选择器选择首选方法:
- 手动设置:手动创建每个文件,以便完全控制项目结构。
- Maven 命令:使用 Maven 原型在一个命令中搭建项目基架。
- Visual Studio Code:使用 VS Code Azure Functions 扩展通过引导 UI 生成项目。
先决条件
若要完成本快速入门指南,你需要:
已安装 Java 开发人员工具包版本 8 或更高版本。
已安装 Apache Maven 版本 3.0 或更高版本。
最新版本的 Azure Functions Core Tools。
对于 Azure Functions 4.x,需要 Core Tools 版本 4.0.4915 或更高版本。
一个 HTTP 测试工具,用于保护数据安全。 有关详细信息,请参阅 HTTP 测试工具。
安装了 Azure Functions 扩展的 Visual Studio Code(只有 Visual Studio Code 设置路径才需要)。
一份 Azure 订阅。 若要使用 Durable Functions,必须具有 Azure 存储帐户。
如果没有 Azure 帐户,请在开始前创建一个免费帐户。
向项目添加所需的依赖项和插件
将以下代码添加到 pom.xml 文件。 在复制之前,请将 your-unique-app-name 替换为一个全局唯一的函数应用名称。 调整region、javaVersion和resourceGroup以匹配您的环境。
<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>
添加所需的 JSON 文件
将 host.json 文件添加到项目目录。 它应如下例所示:
{
"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)"
}
}
注释
Java Durable Functions 需要扩展捆绑包 v4。 不支持早期捆绑包。 有关详细信息,请参阅 扩展捆绑包文档。
Durable Functions 需要存储提供程序来存储运行时状态。 将 local.settings.json 文件添加到项目目录以配置存储提供程序。 若要使用 Azure 存储作为提供程序,请将 AzureWebJobsStorage 值设置为 Azure 存储帐户的连接字符串:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "<your storage account connection string>",
"FUNCTIONS_WORKER_RUNTIME": "java"
}
}
Important
local.settings.json 文件可以包含机密。 请确保将其添加到 .gitignore 文件,以避免将其提交到源代码管理。
创建 Durable Functions 业务流程协调程序、活动和客户端函数
以下示例代码显示了每种函数类型的基本示例:
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();
}
}
使用 Maven 命令创建本地Durable Functions项目
运行以下命令,生成一个包含 Durable Functions 应用的基本函数的项目:
mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DarchetypeVersion=1.62 -Dtrigger=durablefunctions
根据提示提供以下信息:
| 提示 | Action |
|---|---|
| groupId | 输入 com.function。 |
| artifactId | 输入 myDurableFunction。 |
| 版本 | 选择 1.0-SNAPSHOT。 |
| 包 | 输入 com.function。 |
| Y | 输入 Y,然后选择 Enter 键进行确认。 |
现在,你有一个本地项目,其中包含基本 Durable Functions 应用中的三个函数。 该原型会自动将 com.microsoft:durabletask-azure-functions 作为依赖项添加到你的 pom.xml 文件中。
为 Durable Functions 配置后端存储提供程序
Durable Functions 需要存储提供程序来存储运行时状态。 可以在 local.settings.json 中将 Azure 存储设置为存储提供程序。 使用 Azure 存储帐户的连接字符串作为 AzureWebJobsStorage 的值,如以下示例所示:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "<your storage account connection string>",
"FUNCTIONS_WORKER_RUNTIME": "java"
}
}
Important
local.settings.json 文件可以包含机密。 请确保将其添加到 .gitignore 文件,以避免将其提交到源代码管理。
创建本地项目
在Visual Studio Code中,选择 F1(或选择 Ctrl/Cmd+Shift+P)以打开命令面板。 在提示符 (
>) 处输入命令,然后选择“Azure Functions: 创建新项目”。
选择浏览。 在“选择文件夹”对话框中,转到要用于项目的文件夹,然后选择“选择”。
根据提示提供以下信息:
提示 Action 选择语言 选择“Java”。 选择 Java 版本 选择 Java 8 或更高版本。 在 Azure 中选择运行函数的 Java 版本,然后选择在本地验证的 Java 版本。 提供组 ID 输入 com.function。 提供项目 ID 输入 myDurableFunction。 提供版本 输入 1.0-SNAPSHOT。 提供包名称 输入 com.function。 提供应用名称 输入 myDurableFunction。 选择用于Java项目的生成工具 选择“Maven”。 选择您希望打开项目的方式 选择“在新窗口中打开”。
现在,你有一个包含示例 HTTP 函数的项目。 可以删除生成的 HTTP 函数,因为你将在下一步中添加 Durable Functions。
向项目添加函数
在命令面板中,输入并选择“Azure Functions:创建函数。
对于“更改模板筛选器”,请选择“全部”。
根据提示提供以下信息:
提示 Action 选择函数的模板 选择“DurableFunctionsOrchestration”。 提供包名称 输入 com.function。 提供函数名称 输入 DurableFunctionsOrchestrator。 在对话框中,选择“选择存储帐户”设置存储帐户,然后按照提示进行操作。
现在,应该为 Durable Functions 应用生成了三个基本函数。
为Durable Functions配置 pom.xml 和 host.json
将以下依赖项添加到 pom.xml 文件:
<dependency>
<groupId>com.microsoft</groupId>
<artifactId>durabletask-azure-functions</artifactId>
<version>1.0.0</version>
</dependency>
将 extensions 属性添加到 host.json 文件。 如果文件已有其他属性,请将 extensions 块合并到现有 JSON 中:
{
"version": "2.0",
"extensions": {
"durableTask": {
"hubName": "JavaTestHub"
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
在本地测试函数
使用 Azure Functions Core Tools,可以在本地开发计算机上运行 Azure Functions 项目。
如果使用的是 Visual Studio Code,请打开新的终端窗口,并运行以下命令来生成项目:
mvn clean package然后,运行持久函数:
mvn azure-functions:run在终端面板中,复制 HTTP 触发的函数的 URL 终结点。
使用 HTTP 测试工具 将 HTTP POST 请求发送到 URL 终结点。
响应应当类似于以下示例:
{ "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..." }响应是 HTTP 函数的初始结果。 它让你知道持久业务流程已成功启动。 它尚未显示编排的最终结果。 响应中包括了几个有用的 URL。 现在,查询业务流程的状态。
复制
statusQueryGetUri的 URL 值,将其粘贴到浏览器的地址栏中,然后执行请求。 或者,可继续使用 HTTP 测试工具发出 GET 请求。请求将查询业务流程实例的状态。 应该会看到实例已完成,并且它包含持久函数的输出或结果,如以下示例所示:
{ "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" }