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

Durable Functions 中的函数链 - Hello 序列示例

函数链是指以特定顺序执行一系列函数的模式。 通常需要将一个函数的输出应用于另一函数的输入。 本文介绍在完成 Durable Functions 快速入门(C#JavaScriptPythonPowerShellJava)时创建的链接序列。 有关 Durable Functions 的详细信息,请参阅 Durable Functions 概述

先决条件

函数

本文介绍示例应用中的以下函数:

  • E1_HelloSequence:在一个序列中多次调用 E1_SayHello 的一个业务流程协调程序函数。 它存储来自 E1_SayHello 调用的输出并记录结果。
  • E1_SayHello:在字符串前添加“Hello”的一个活动函数
  • HttpStart:HTTP 触发的持久客户端函数,用于启动业务流程协调程序的实例。

E1_HelloSequence 业务流程协调程序函数

[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello_DirectInput", "London"));

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

所有 C# orchestration 函数都必须具有 DurableOrchestrationContext 类型的参数,此参数存在于 Microsoft.Azure.WebJobs.Extensions.DurableTask 程序集中。 借助此上下文对象,可使用其 CallActivityAsync 方法调用其他活动 函数并传递输入参数。

代码将在具有不同参数值的序列中调用三次 E1_SayHello。 每个调用的返回值都会添加到 outputs 列表,函数末尾会返回该列表。

E1_SayHello 活动函数

[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
    string name = context.GetInput<string>();
    return $"Hello {name}!";
}

活动使用了 ActivityTrigger 属性。 使用提供的 IDurableActivityContext 执行活动相关操作,例如,使用 GetInput<T> 访问输入值。

E1_SayHello 的实现是一种相对简单的字符串格式设置操作。

可以直接绑定到传递给活动函数的类型,而非绑定到 IDurableActivityContext。 例如:

[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
    return $"Hello {name}!";
}

HttpStart 客户端函数

可以使用客户端函数启动业务流程协调程序函数的实例。 你将使用 HTTP 触发的函数 HttpStart 启动 E1_HelloSequence 的实例。

public static class HttpStart
{
    [FunctionName("HttpStart")]
    public static async Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
        [DurableClient] IDurableClient 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}'.");

        return starter.CreateCheckStatusResponse(req, instanceId);
    }
}

若要与业务流程协调程序进行交互,函数必须包含 DurableClient 输入绑定。 你使用客户端来启动业务流程。 它还可以帮助你返回 HTTP 响应,并在其中包含用于检查新业务流程状态的 URL。

运行示例

若要执行 E1_HelloSequence 业务流程,请将以下 HTTP POST 请求发送到 HttpStart 函数。

POST http://{host}/orchestrators/E1_HelloSequence

注意

前面的 HTTP 代码片段假定 host.json 文件中有一个条目,该条目从所有 HTTP 触发器函数 URL 中删除默认的 api/ 前缀。 可以在示例的 host.json 文件中找到此配置的标记。

例如,如果在名为“myfunctionapp”的函数应用中运行示例,请将 "{host}" 替换为“myfunctionapp.azurewebsites.net”。

结果为 HTTP 202 响应,如下所示(已简化):

HTTP/1.1 202 Accepted
Content-Length: 719
Content-Type: application/json; charset=utf-8
Location: http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

(...trimmed...)

此时,业务流程已进行排队,并将立即开始运行。 Location 标头中的 URL可用于检查执行的状态。

GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

结果为业务流程的状态。 它运行和完成的速度很快,因此处于已完成 状态,并伴有如下所示响应(已简化):

HTTP/1.1 200 OK
Content-Length: 179
Content-Type: application/json; charset=utf-8

{"runtimeStatus":"Completed","input":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2017-06-29T05:24:57Z","lastUpdatedTime":"2017-06-29T05:24:59Z"}

可以看到,实例的 runtimeStatus 为已完成 ,且 output 包含 orchestrator 函数执行的 JSON 序列化结果。

注意

可对其他触发器类型(如 queueTriggereventHubTriggertimerTrigger)实施类似的启动器逻辑。

查看函数执行日志。 由于业务流程可靠性主题中所述的重播行为,E1_HelloSequence 函数已多次启动和完成。 另一方面,由于未重播这些函数执行,因此只执行三次 E1_SayHello

后续步骤

此示例演示了简单的函数链业务流程。 下一示例演示如何实现扇出/扇入模式。