在 Azure 中的 Durable Functions 中管理实例

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

启动实例

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

用于启动新编排实例的参数如下所示:

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

小窍门

尽可能为实例 ID 使用随机标识符。 在跨多个 VM 缩放业务流程协调程序函数时,随机实例 ID 有助于确保负载分布相等。 使用非随机实例 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

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

  • 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 命令将启动消息排入目标任务中心,但业务流程实际上不会运行,除非有一个可以处理消息的函数应用主机进程。

注释

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

以下命令启动名为 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:以下值之一:
    • 待决:实例已被调度,但尚未开始运行。
    • 正在运行:实例已开始运行。
    • 已完成:实例已正常完成。
    • ContinuedAsNew:实例已重启,历史记录已更新。 此状态是暂时性状态。
    • 失败:实例失败并出现错误。
    • 已终止:实例突然停止。
    • 已暂停:实例已暂停,可能会在以后的时间点恢复。
  • 历史记录:业务流程的执行历史记录。 仅当 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 中的命令获取编排实例的状态。

注释

目前仅当使用默认 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 来查询 任务中心内所有业务流程实例的状态。 此 “list-instances”“get-status” 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

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

注释

目前仅在使用默认 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 命令与筛选器一起使用。 除了上述top参数、continuation-tokenconnection-string-setting参数和task-hub-name参数外,还可以使用三个筛选器参数(created-aftercreated-beforeruntime-status)。

注释

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

下面是命令的参数 durable get-instances

  • created-after (可选):检索在此日期/时间之后创建的实例(UTC)。 接受 ISO 8601 格式的日期/时间。
  • created-before (可选):检索在此日期/时间(UTC)之前创建的实例。 接受 ISO 8601 格式的日期/时间。
  • runtime-status (可选):检索具有特定状态的实例(例如正在运行或已完成)。 可以提供多个状态(用空格分隔)。
  • 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)
{
    // To suspend an orchestration
    string suspendReason = "Need to pause workflow";
    await client.SuspendAsync(instanceId, suspendReason);
    
    // To resume an orchestration
    string resumeReason = "Continue workflow";
    await client.ResumeAsync(instanceId, resumeReason);
}

挂起的实例最终将转换为 Suspended 状态。 但是,这种转换不会立即发生。 相反,挂起操作将与该实例的其他操作一起排入任务集线器。 可以使用实例查询 API 来知道正在运行的实例何时实际达到挂起状态。

当挂起的协调器被恢复时,其状态将恢复为 Running

Azure Functions Core Tools

还可以通过使用 Core Tools 的命令直接终止协调实例。

注释

目前,仅当使用默认 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

还可以使用 func durable raise-event Core Tools 中的命令直接将事件引发到编排实例。

注释

目前仅当使用默认 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 秒。

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

// 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 列表

可以使用外部系统来监控或向编排触发事件。 外部系统可以通过 Webhook URL 与 Durable Functions 通信,这些 URL 是 HTTP API URL 发现中所述的默认响应的一部分。 可以使用编排客户端绑定以编程方式访问 Webhook 的 URL。 具体而言, 可以使用创建 HTTP 管理有效负载 API 来获取包含这些 Webhook URL 的可序列化对象。

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

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

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

  • ID:编排的实例 ID(应与 InstanceId 输入相同)。
  • StatusQueryGetUri:业务流程实例的状态 URL。
  • SendEventPostUri:流程实例的“引发事件”URL。
  • TerminatePostUri:协调实例的“terminate”URL。
  • PurgeHistoryDeleteUri:业务流程实例的“清除历史记录”URL。
  • suspendPostUri:编排实例的“suspend”URL。
  • resumePostUri:编排实例的“resume”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 不应替代正确的错误处理和重试策略。 相反,它仅用于编排实例因意外原因而失败的情况。 除了Failed状态以外的状态(例如,RunningPendingTerminatedCompleted)中的业务流程不能被“重排”。 有关错误处理和重试策略的详细信息,请参阅 错误处理 文章。

使用编排客户端绑定RewindAsync 方法(.NET)或rewind 方法(JavaScript),将编排重新置于“正在运行”状态。 此方法还将重新运行导致业务流程编排失败的活动或子业务流程执行失败。

例如,假设你有一个涉及一系列 人工审批的工作流。 假设有一系列活动函数通知某人需要审批,并等待实时响应。 在所有审批活动收到响应或超时后,假设另一个活动因应用程序配置错误(例如数据库连接字符串无效)而失败。 结果是编排故障发生在工作流中。 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 命令直接回退编排实例。

注释

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

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,该 API 由编排客户端定义。

第一个示例演示如何删除单个编排实例。

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

下一个示例显示计时器触发的函数,该函数清除指定时间间隔后完成的所有业务流程实例的历史记录。 在这种情况下,它会删除 30 天或多天前完成的所有实例的数据。 本示例函数计划每天运行一次,UTC 下午 12:00:

[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 版本一文。

注释

要使清除历史记录作成功,目标实例的运行时状态必须为 “已完成”、“ 终止”或 “失败”。

Azure Functions Core Tools

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

注释

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

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

  • created-after (可选):清除在此日期/时间之后创建的实例的历史记录(UTC)。 接受 ISO 8601 格式的日期/时间。
  • created-before (可选):清除在此日期/时间之前创建的实例的历史记录(UTC)。 接受 ISO 8601 格式的日期/时间。
  • runtime-status (可选):清除具有特定状态的实例的历史记录(例如正在运行或已完成)。 可以提供多个状态(用空格分隔)。
  • 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

删除任务中心

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

注释

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

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

后续步骤