你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Azure 中管理 Durable Functions 中的实例

Durable Functions 中的业务流程是长时间运行的有状态函数,可使用内置管理 API 来启动、查询、暂停、继续和终止。 Durable Functions 业务流程客户端绑定还公开了其他几种实例管理 API,例如向实例发送外部事件、清除实例历史记录等。本文详细介绍了所有受支持的实例管理操作。

启动实例

业务流程客户端绑定上的 start-new(或 schedule-new)方法可启动新业务流程实例。 在内部,此方法通过 Durable Functions 存储提供程序写入消息,然后将其返回。 此消息以异步方式触发具有指定名称的业务流程函数的启动过程。

用于启动新业务流程实例的参数如下所示:

  • 名称:要计划的业务流程协调程序函数的名称。
  • 输入:应作为输入传递给业务流程协调程序函数的任何 JSON 可序列化数据。
  • InstanceId:(可选)实例的唯一 ID。 如果未指定此参数,该方法将使用随机 ID。

提示

尽可能为实例 ID 使用随机标识符。 随机实例 ID 有助于确保在多个 VM 上缩放业务流程协调程序函数时均衡分配负载。 使用非随机实例 ID 的适当时机是 ID 必须来自外部源,或实现单一实例业务流程协调程序模式时。

以下代码是一个示例函数,用于启动新的业务流程实例:

[FunctionName("HelloWorldQueueTrigger")]
public static async Task Run(
    [QueueTrigger("start-queue")] string input,
    [DurableClient] IDurableOrchestrationClient starter,
    ILogger log)
{
    string instanceId = await starter.StartNewAsync("HelloWorld", input);
    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,并且必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

Azure Functions Core Tools

还可直接使用 Core Tools 中的 func durable start-new 命令启动实例,这需要以下参数:

  • function-name(必需) :要启动的函数的名称。
  • input(可选) :以内联方式或通过 JSON 文件提供的函数输入。 对于文件,请使用 @ 将路径前缀添加到文件,例如 @path/to/file.json
  • id(可选) :业务流程实例的 ID。 如果未指定此参数,该命令将使用随机 GUID。
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认值为 AzureWebJobsStorage。
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认值为 DurableFunctionsHub。 也可以使用 durableTask:HubName 在 host.json 中设置此参数。

注意

Core Tools 命令假设要从函数应用的根目录运行这些命令。 如果显式提供了 connection-string-settingtask-hub-name 参数,则可以从任何目录运行这些命令。 尽管无需运行函数应用主机即可运行这些命令,但除非运行主机,否则可能观察不到某些效果。 例如,start-new 命令会在目标任务中心内将某个启动消息排队,但除非某个正在运行的函数应用程序主机进程可以处理该消息,否则业务流程实际上不会运行。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

以下命令启动名为 HelloWorld 的函数,并将文件 counter-data.json 的内容传递到该函数:

func durable start-new --function-name HelloWorld --input @counter-data.json --task-hub-name TestTaskHub

查询实例

启动新的业务流程实例后,你很可能需要查询其运行时状态,以了解它们是否正在运行、已完成或已失败。

业务流程客户端绑定上的 get-status 方法查询业务流程实例的状态。

它采用 instanceId(必需)、showHistory(可选)、showHistoryOutput(可选)和 showInput(可选)作为参数。

  • showHistory :如果设置为 true,则响应包含执行历史记录。
  • showHistoryOutput :如果设置为 true,则执行历史记录包含活动输出。
  • showInput :如果设置为 false,则响应不会包含函数的输入。 默认值为 true

此方法返回包含以下属性的对象:

  • 名称:业务流程协调程序函数的名称。
  • InstanceId:业务流程的实例 ID(应与 instanceId 输入相同)。
  • CreatedTime:业务流程协调程序函数开始运行的时间。
  • LastUpdatedTime:上次创建业务流程检查点的时间。
  • 输入:函数的输入,采用 JSON 值形式。 如果 showInput 为 false,则不会填充此字段。
  • CustomStatus:JSON 格式的自定义业务流程状态。
  • 输出:函数的输出,采用 JSON 值形式(如果该函数已完成)。 如果业务流程协调程序函数失败,则此属性包含失败详细信息。 如果业务流程协调程序函数已暂停或已终止,则此属性包含暂停或终止原因(如果有)。
  • RuntimeStatus:以下值之一:
    • Pending:实例已计划但尚未开始运行。
    • 正在运行:实例已开始运行。
    • Completed:实例已正常完成。
    • ContinuedAsNew:实例已重启自身并生成了新历史记录。 此状态是暂时性状态。
    • 失败:实例失败并出错。
    • 已终止:实例突然停止。
    • 已暂停:该实例已暂停,可能会在以后的某个时间点继续。
  • History:业务流程的执行历史记录。 仅当 showHistory 设置为 true 时,才填充此字段。

注意

业务流程协调程序在其所有计划的任务完成并且业务流程协调程序返回后才会标记为 Completed。 换句话说,业务流程协调程序到达其 return 语句不足以将其标记为 Completed。 这尤其适用于使用 WhenAny 的情况;这些业务流程协调程序经常在执行所有计划的任务之前 return

如果实例不存在,此方法会返回 null(.NET 和 Java)、undefined (JavaScript) 或 None (Python)。

[FunctionName("GetStatus")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("check-status-queue")] string instanceId)
{
    DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId);
    // do something based on the current status.
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,并且必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

Azure Functions Core Tools

也可直接使用 Core Tools 中的 func durable get-runtime-status 命令获取业务流程实例的状态。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

durable get-runtime-status 命令采用以下参数:

  • id(必需) :业务流程实例的 ID。
  • show-input(可选) :如果设置为 true,则响应包含函数的输入。 默认值为 false
  • show-output(可选) :如果设置为 true,则响应包含函数的输出。 默认值为 false
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认为 DurableFunctionsHub。 也可以使用 durableTask:HubName 在 host.json 中设置此参数。

以下命令检索业务流程实例 ID 为 0ab8c55a66644d68a3a8b220b12d209c 的实例的状态(包括输入和输出)。 假设从函数应用的根目录运行 func 命令:

func durable get-runtime-status --id 0ab8c55a66644d68a3a8b220b12d209c --show-input true --show-output true

可以使用 durable get-history 命令检索业务流程实例的历史记录。 它采用了以下参数:

  • id(必需) :业务流程实例的 ID。
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认为 DurableFunctionsHub。 也可以使用 durableTask:HubName 在 host.json 中设置此参数。
func durable get-history --id 0ab8c55a66644d68a3a8b220b12d209c

查询所有实例

可以使用语言 SDK 中的 API 查询 任务中心中所有业务流程实例的状态。 “列出实例”或“获取状态”API 会返回对象列表,这些对象表示与查询参数匹配的业务流程实例。

[FunctionName("GetAllStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    var noFilter = new OrchestrationStatusQueryCondition();
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        noFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
    
    // Note: ListInstancesAsync only returns the first page of results.
    // To request additional pages provide the result.ContinuationToken
    // to the OrchestrationStatusQueryCondition's ContinuationToken property.
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,并且必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

Azure Functions Core Tools

也可直接使用 Core Tools 中的 func durable get-instances 命令查询实例。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

durable get-instances 命令采用以下参数:

  • top(可选) :此命令支持分页。 此参数对应于每个请求检索的实例数。 默认值为 10。
  • continuation-token(可选) :用于指示要检索的实例页或节的标记。 每次执行 get-instances 都会向下一个实例集返回一个标记。
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认为 DurableFunctionsHub。 也可以使用 durableTask:HubName 在 host.json 中设置此参数。
func durable get-instances

使用筛选器查询实例

如果你实际上并不需要标准实例查询可以提供的所有信息,应该怎样做? 例如,你只需要查找业务流程的创建时间或业务流程的运行时状态。 为此,可以通过应用筛选器来缩小查询范围。

[FunctionName("QueryStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    // Get the first 100 running or pending instances that were created between 7 and 1 day(s) ago
    var queryFilter = new OrchestrationStatusQueryCondition
    {
        RuntimeStatus = new[]
        {
            OrchestrationRuntimeStatus.Pending,
            OrchestrationRuntimeStatus.Running,
        },
        CreatedTimeFrom = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)),
        CreatedTimeTo = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)),
        PageSize = 100,
    };
    
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        queryFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,并且必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

Azure Functions Core Tools

在 Azure Functions Core Tools 中,还可以结合筛选器使用 durable get-instances 命令。 除了前面提到的 topcontinuation-tokenconnection-string-settingtask-hub-name 参数以外,还可以使用三个筛选器参数(created-aftercreated-beforeruntime-status)。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

以下是 durable get-instances 命令的参数。

  • created-after(可选) :检索在此日期/时间 (UTC) 之后创建的实例。 接受 ISO 8601 格式的日期时间。
  • created-before(可选) :检索在此日期/时间 (UTC) 之前创建的实例。 接受 ISO 8601 格式的日期时间。
  • runtime-status(可选) :检索具有特定状态(例如 running 或 completed)的实例。 可以提供多个状态(用空格分隔)。
  • top(可选) :每个请求检索的实例数。 默认值为 10。
  • continuation-token(可选) :用于指示要检索的实例页或节的标记。 每次执行 get-instances 都会向下一个实例集返回一个标记。
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认为 DurableFunctionsHub。 也可以使用 durableTask:HubName 在 host.json 中设置此参数。

如果未提供任何筛选器(created-aftercreated-beforeruntime-status),则无论运行时状态或创建时间是什么,该命令都会检索 top 实例。

func durable get-instances --created-after 2021-03-10T13:57:31Z --created-before  2021-03-10T23:59Z --top 15

终止实例

如果需要花费太长的时间来运行某个业务流程实例,或者出于某种原因需要提前将其停止,则可以将其终止。

“终止”API 的两个参数为“实例 ID”和“原因”字符串,将写入日志和实例状态。

[FunctionName("TerminateInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("terminate-queue")] string instanceId)
{
    string reason = "Found a bug";
    return client.TerminateAsync(instanceId, reason);
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,并且必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

终止的实例最终会转换为 Terminated 状态。 但是,这种转换不会立即发生。 而是,终止操作将与该实例的其他操作一起在任务中心排队。 可以使用实例查询 API 来了解已终止的实例实际何时达到 Terminated 状态。

注意

当前不会传播实例终止。 无论调用活动函数和子业务流程的业务流程实例是否已终止,活动函数和子业务流程都将运行至完成状态。

暂停和继续实例

暂停业务流程允许你停止正在运行的业务流程。 与终止不同,你可以选择在稍后的时间点继续暂停的业务流程协调程序。

“暂停”API 的两个参数为“实例 ID”和“原因”字符串,它们将写入到日志和实例状态。

[FunctionName("SuspendResumeInstance")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("suspend-resume-queue")] string instanceId)
{
    string suspendReason = "Need to pause workflow";
    await client.SuspendAsync(instanceId, suspendReason);
    
    // Wait for 30 seconds to ensure that the orchestrator state is updated to suspended. 
    DateTime dueTime = context.CurrentUtcDateTime.AddSeconds(30);
    await context.CreateTimer(dueTime, CancellationToken.None);
    
    string resumeReason = "Continue workflow";
    await client.ResumeAsync(instanceId, resumeReason);
}

暂停的实例最终会转换为 Suspended 状态。 但是,这种转换不会立即发生。 而是,暂停操作将与该实例的其他操作一起在任务中心排队。 可以使用实例查询 API 来了解正在运行的实例何时实际达到“暂停”状态。

继续暂停的业务流程协调程序时,其状态将更改回 Running

Azure Functions Core Tools

也可直接使用 Core Tools 中的 func durable terminate 命令终止业务流程实例。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

durable terminate 命令采用以下参数:

  • id(必需) :要终止的业务流程实例的 ID。
  • reason(可选) :终止的原因。
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认为 DurableFunctionsHub。 也可以使用 durableTask:HubName 在 host.json 中设置此参数。

以下命令终止 ID 为 0ab8c55a66644d68a3a8b220b12d209c 的业务流程实例:

func durable terminate --id 0ab8c55a66644d68a3a8b220b12d209c --reason "Found a bug"

将事件发送到实例

在某些方案中,业务流程协调程序函数需要等待和侦听外部事件。 有用的示例方案包括监视人机交互方案。

可以使用业务流程客户端的“引发事件”API 将事件通知发送到正在运行的实例。 业务流程可以使用“等待外部事件”业务流程协调程序 API 侦听和响应这些事件。

“引发事件”的参数如下:

  • 实例 ID:实例的唯一 ID。
  • 事件名称:要发送的事件的名称。
  • 事件数据:要发送到实例的 JSON 可序列化有效负载。
[FunctionName("RaiseEvent")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("event-queue")] string instanceId)
{
    int[] eventData = new int[] { 1, 2, 3 };
    return client.RaiseEventAsync(instanceId, "MyEvent", eventData);
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,并且必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

注意

如果没有具有指定实例 ID 的业务流程实例,则会丢弃事件消息。 如果实例存在但尚未等待事件,则事件会以实例状态进行存储,直到它做好被接收和处理的准备。

Azure Functions Core Tools

也可直接使用 Core Tools 中的 func durable raise-event 命令向业务流程实例引发事件。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

durable raise-event 命令采用以下参数:

  • id(必需) :业务流程实例的 ID。
  • event-name :要引发的事件的名称。
  • event-data(可选) :要发送到业务流程实例的数据。 这可以是某个 JSON 文件的路径,或者,你可以直接在命令行中提供数据。
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认为 DurableFunctionsHub。 也可以使用 durableTask:HubName 在 host.json 中设置此参数。
func durable raise-event --id 0ab8c55a66644d68a3a8b220b12d209c --event-name MyEvent --event-data @eventdata.json
func durable raise-event --id 1234567 --event-name MyOtherEvent --event-data 3

等待业务流程完成

在长时间运行的业务流程中,你可能想要等待并获取业务流程的结果。 对于这种情况,在业务流程中定义超时期限也可能会很有帮助。 如果超过了超时期限,则应返回业务流程的状态而不是结果。

“等待完成或创建检查状态响应”API 可用于从业务流程实例同步获取实际输出。 默认情况下,此方法的默认超时时间为 10 秒,轮询间隔为 1 秒。

下面的 HTTP 触发型函数示例演示了如何使用此 API:

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace VSSample
{
    public static class HttpSyncStart
    {
        private const string Timeout = "timeout";
        private const string RetryInterval = "retryInterval";

        [FunctionName("HttpSyncStart")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}/wait")]
            HttpRequestMessage req,
            [DurableClient] IDurableOrchestrationClient starter,
            string functionName,
            ILogger log)
        {
            // Function input comes from the request content.
            object eventData = await req.Content.ReadAsAsync<object>();
            string instanceId = await starter.StartNewAsync(functionName, eventData);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            TimeSpan timeout = GetTimeSpan(req, Timeout) ?? TimeSpan.FromSeconds(30);
            TimeSpan retryInterval = GetTimeSpan(req, RetryInterval) ?? TimeSpan.FromSeconds(1);
            
            return await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(
                req,
                instanceId,
                timeout,
                retryInterval);
        }

        private static TimeSpan? GetTimeSpan(HttpRequestMessage request, string queryParameterName)
        {
            string queryParameterStringValue = request.RequestUri.ParseQueryString()[queryParameterName];
            if (string.IsNullOrEmpty(queryParameterStringValue))
            {
                return null;
            }

            return TimeSpan.FromSeconds(double.Parse(queryParameterStringValue));
        }
    }
}

使用以下行调用该函数。 使用 2 秒作为超时,使用 0.5 秒作为重试间隔:

curl -X POST "http://localhost:7071/orchestrators/E1_HelloSequence/wait?timeout=2&retryInterval=0.5"

注意

上述 cURL 命令假定项目中有一个名为 E1_HelloSequence 的业务流程协调程序函数。 因为 HTTP 触发器函数的编写方式,你可以将它替换为项目中任何业务流程协调程序函数的名称。

根据从业务流程实例获取响应所需的时间,存在两种情况:

  • 业务流程实例在定义的超时(在本例中为 2 秒)内完成,响应是同步传送的实际业务流程实例输出:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:14:29 GMT
Transfer-Encoding: chunked

[
    "Hello Tokyo!",
    "Hello Seattle!",
    "Hello London!"
]
  • 业务流程实例无法在定义的超时内完成,响应是 HTTP API URL 发现中所述的默认值:
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:13:51 GMT
Location: http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}
Retry-After: 10
Transfer-Encoding: chunked

{
    "id": "d3b72dddefce4e758d92f4d411567177",
    "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/raiseEvent/{eventName}?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/terminate?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "suspendPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/suspend?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "resumePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/resume?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}"
}

注意

Webhook URL 的格式可能会有所不同,具体取决于所运行 Azure Functions 主机的版本。 前面的示例适用于 Azure Functions 3.0 主机。

检索 HTTP 管理 Webhook URL

可以使用外部系统来监视或引发到业务流程的事件。 外部系统可以通过作为 HTTP API URL 发现中所述的默认响应一部分的 Webhook URL 来与 Durable Functions 通信。 也可使用业务流程客户端绑定以编程方式访问 Webhook URL。 具体来说,可以使用“创建 HTTP 管理有效负载”API 来获取包含这些 Webhook URL 的可序列化对象。

“创建 HTTP 管理有效负载”API 有一个参数:

  • 实例 ID:实例的唯一 ID。

这些方法返回包含以下字符串属性的对象:

  • Id:业务流程的实例 ID(应与 InstanceId 输入相同)。
  • StatusQueryGetUri:业务流程实例的状态 URL。
  • SendEventPostUri:业务流程实例的“引发事件”URL。
  • TerminatePostUri:业务流程实例的“终止”URL。
  • PurgeHistoryDeleteUri:业务流程实例的“清除历史记录”URL。
  • suspendPostUri:业务流程实例的“暂停”URL。
  • resumePostUri:业务流程实例的“继续”URL。

函数可以将这些对象的实例发送到外部系统,以监视或引发相应业务流程中的事件,如以下示例所示:

[FunctionName("SendInstanceInfo")]
public static void SendInstanceInfo(
    [ActivityTrigger] IDurableActivityContext ctx,
    [DurableClient] IDurableOrchestrationClient client,
    [CosmosDB(
        databaseName: "MonitorDB",
        containerName: "HttpManagementPayloads",
        Connection = "CosmosDBConnectionSetting")]out dynamic document)
{
    HttpManagementPayload payload = client.CreateHttpManagementPayload(ctx.InstanceId);

    // send the payload to Azure Cosmos DB
    document = new { Payload = payload, id = ctx.InstanceId };
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 DurableActivityContext 而不是 IDurableActivityContext,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

回退实例(预览)

如果意外的原因导致业务流程失败,可以使用相应的 API 将实例回退到以前的正常状态。

注意

此 API 并不旨在取代适当的错误处理和重试策略。 只能在业务流程实例出于意外的原因而失败时才使用此 API。 处于 Failed 之外的其他状态(例如 RunningPendingTerminatedCompleted)的业务流程无法“回退”。 有关错误处理和重试策略的详细信息,请参阅错误处理一文。

请使用业务流程客户端绑定RewindAsync (.NET) 或 rewind (JavaScript) 方法将业务流程恢复到 Running 状态。 此方法还会重新运行导致业务流程失败的活动或子业务流程执行失败操作。

例如,假设某个工作流涉及到一系列人工审批。 假设有一系列活动函数会通知某人做出审批并等待其实时响应。 在所有审批活动收到响应或超时后,假设另一活动因应用程序配置错误(例如数据库连接字符串无效)而失败。 结果是业务流程在工作流的深入阶段发生失败。 使用 RewindAsync (.NET) 或 rewind (JavaScript) API,应用程序管理员可以修复配置错误并将失败的业务流程回退到失败前的状态。 无需再次审批任何人工交互步骤,业务流程现可成功完成。

注意

回退功能不支持回退使用持久计时器的业务流程实例。

[FunctionName("RewindInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("rewind-queue")] string instanceId)
{
    string reason = "Orchestrator failed and needs to be revived.";
    return client.RewindAsync(instanceId, reason);
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,并且必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

Azure Functions Core Tools

也可直接使用 Core Tools 中的 func durable rewind 命令后退业务流程实例。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

durable rewind 命令采用以下参数:

  • id(必需) :业务流程实例的 ID。
  • reason(可选) :回退业务流程实例的原因。
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认使用 host.json 文件中的任务中心名称。
func durable rewind --id 0ab8c55a66644d68a3a8b220b12d209c --reason "Orchestrator failed and needs to be revived."

清除实例历史记录

若要删除与业务流程关联的所有数据,可以清除实例历史记录。 例如,你可能想要删除与完成的实例相关联的所有存储资源。 为此,请使用业务流程客户端定义的“清除实例”API。

第一个示例演示如何清除单个业务流程实例。

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("purge-queue")] string instanceId)
{
    return client.PurgeInstanceHistoryAsync(instanceId);
}

接下来的示例演示一个计时器触发的函数,该函数清除在指定的时间间隔后完成的所有业务流程实例的历史记录。 在本例中,该函数将删除 30 天或更长时间以前完成的所有实例的数据。 此示例函数计划在每天下午 12:00 UTC 运行一次:

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [TimerTrigger("0 0 12 * * *")] TimerInfo myTimer)
{
    return client.PurgeInstanceHistoryAsync(
        DateTime.MinValue,
        DateTime.UtcNow.AddDays(-30),  
        new List<OrchestrationStatus>
        {
            OrchestrationStatus.Completed
        });
}

注意

前面的 C# 代码适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 OrchestrationClient 属性而不是 DurableClient 属性,并且必须使用 DurableOrchestrationClient 参数类型而不是 IDurableOrchestrationClient。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

注意

若要成功完成清除历史记录的操作,目标实例的运行时状态必须是 CompletedTerminatedFailed

Azure Functions Core Tools

可使用 Core Tools 中的 func durable purge-history 命令清除业务流程实例的历史记录。 类似于前一部分中的第二个 C# 示例,该命令将清除在指定时间间隔内创建的所有业务流程实例的历史记录。 可按运行时状态进一步筛选已清除的实例。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

durable purge-history 命令有多个参数:

  • created-after(可选) :清除此日期/时间 (UTC) 之后创建的实例的历史记录。 接受 ISO 8601 格式的日期时间。
  • created-before(可选) :清除此日期/时间 (UTC) 之前创建的实例的历史记录。 接受 ISO 8601 格式的日期时间。
  • runtime-status(可选) :清除具有特定状态(例如 running 或 completed)的实例的历史记录。 可以提供多个状态(用空格分隔)。
  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认使用 host.json 文件中的任务中心名称。

以下命令将删除在 2021 年 11 月 14 日下午 7:35 (UTC) 之前创建的所有失败实例的历史记录。

func durable purge-history --created-before 2021-11-14T19:35:00.0000000Z --runtime-status failed

删除任务中心

通过使用 Core Tools 中的 func durable delete-task-hub 命令,可删除与特定任务中心关联的所有存储项目,包括 Azure 存储表、队列和 Blob。

注意

当前仅在使用默认的 Azure 存储提供程序来保持运行时状态时,才支持 Core Tools 命令。

durable delete-task-hub 命令有两个参数:

  • connection-string-setting(可选) :包含要使用的存储连接字符串的应用程序设置的名称。 默认为 AzureWebJobsStorage
  • task-hub-name(可选) :要使用的 Durable Functions 任务中心的名称。 默认使用 host.json 文件中的任务中心名称。

以下命令删除与 UserTest 任务中心关联的所有 Azure 存储数据。

func durable delete-task-hub --task-hub-name UserTest

后续步骤