Durable Functions 中的永久编排 (Azure Functions)

永恒编排函数 是永不结束的协调器函数。 如果要将 Durable Functions 用于聚合器和任何需要无限循环的方案,它们非常有用。

调度历史记录

业务流程历史记录 主题中所述,Durable Task Framework 会跟踪每个函数业务流程的历史记录。 只要协调器函数继续调度新任务,此历史记录就会持续增长。 如果业务流程协调程序函数进入无限循环并持续计划工作,则此历史记录可能会大幅增长,并导致严重的性能问题。 永恒编排概念旨在缓解需要无限循环的应用程序出现此类问题。

重置和重启

协调器函数通过调用continue-as-new协调触发器绑定的方法来重置其状态,而不是使用无限循环。 此方法采用 JSON 可序列化参数,该参数将成为下一个业务流程协调程序函数生成的新输入。

调用 continue-as-new时,业务流程实例会用新的输入值重启自身。 保留相同的实例 ID,但协调器函数的历史记录将被重置。

持续编排注意事项

在编排流程中使用 continue-as-new 方法时,请记住以下注意事项:

  • 使用 continue-as-new 方法重置协调器函数时,Durable Task Framework 会维护相同的实例 ID,但在内部会创建并使用新的 执行 ID。 此执行 ID 不会在外部公开,但在调试业务流程执行时可能很有用。

  • 在执行期间发生未经处理的异常时,业务流程将进入 失败 状态并终止执行。 在此状态下,从 continue-as-new try-catch 语句块发出的对 finally 的调用不能重新启动编排。

重要

如果在执行过程中业务流程遇到未捕获的异常,则业务流程将进入“失败”状态,执行将完成。 具体而言,这意味着即使在 块中调用 finally,也不会在未被捕获的异常情况下重启业务流程。

定期工作示例

永恒编排的一个用例是需要无限期周期性执行工作的代码。

[FunctionName("Periodic_Cleanup_Loop")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    await context.CallActivityAsync("DoCleanup", null);

    // sleep for one hour between cleanups
    DateTime nextCleanup = context.CurrentUtcDateTime.AddHours(1);
    await context.CreateTimer(nextCleanup, CancellationToken.None);

    context.ContinueAsNew(null);
}

注释

前面的 C# 示例适用于 Durable Functions 2.x。 对于 Durable Functions 1.x,必须使用 DurableOrchestrationContext 而不是 IDurableOrchestrationContext。 有关版本之间差异的详细信息,请参阅 Durable Functions 版本一文。

此示例与计时器触发的函数之间的差异在于清理操作的触发时机不是基于预定时间表。 例如,每小时执行一个函数的 CRON 计划以 1:00、2:00、3:00 等方式运行,并可能遇到重叠问题。 但是,在此示例中,如果清理需要 30 分钟,则计划为 1:00、2:30、4:00 等,并且没有重叠的机会。

启动永恒编排

使用 start-newschedule-new durable client 方法启动持久编排,就像启动其他任何编排函数一样。

注释

如果需要确保单例永久协调程序正在运行,请务必在启动该协调程序时使用同一实例 id 。 有关详细信息,请参阅 实例管理

[FunctionName("Trigger_Eternal_Orchestration")]
public static async Task<HttpResponseMessage> OrchestrationTrigger(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage request,
    [DurableClient] IDurableOrchestrationClient client)
{
    string instanceId = "StaticId";

    await client.StartNewAsync("Periodic_Cleanup_Loop", instanceId); 
    return client.CreateCheckStatusResponse(request, instanceId);
}

注释

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

退出永恒编排

如果业务流程协调程序函数需要最终完成,则只需不要调用ContinueAsNew并让函数退出。

如果业务流程协调程序函数处于无限循环中并且需要停止,请使用业务流程客户端绑定终止 API 来停止它。 有关详细信息,请参阅 实例管理

后续步骤