30

Azure编配器简化有状态无服务器工作流的创建

 5 years ago
source link: http://www.infoq.com/cn/news/2018/09/azure-durable-function-intro?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Azure Durable Functions 旨在通过引入编排器function概念来定义更复杂的工作流,以此来扩展无服务器计算范式。如果你曾经想过要使用它们,微软刚刚 发布了一个示例 ,帮助开发人员开始他们的无服务器计算和编排器function之旅。

Azure Functions是微软在无服务器计算方面的所采取的动作,提供了一种基本机制,可以接受输入,处理输入,并在触发器执行后返回结果。Durable Functions以一种有趣的方式对其进行扩展,它们将状态添加原本的核心无状态中。Durable Functions是一组function,编配器function会将它们打包在一个逻辑事务中。开发人员可以在代码中编写复杂的工作流并执行它们。

Azure Functions背后的两个基本 概念 是function和 触发器 。function是静态类中的一个方法。触发器是指某些代码需要对其做出响应的事件。Http是典型的触发器,它对来自用户的HTTP请求做出响应,以及Timer,它能够调度执行某些代码。最重要的是,Durable Functions提供了两个新概念:

  • 编配器function,可以看作是一种基于云的协程。换句话说,编配器function能够在执行期间设置检查点,可以在等待其他function完成执行时退出,然后从停止的位置继续执行。
  • 活动function,也即可以用在编配器内部的function。它们只能对调用它们的编配器做出响应。活动function结果会被缓存起来,并且同一个编配器实例只执行一次活动function。下面是一个获取GitHub存储库列表的活动function的示例:
[FunctionName("GetAllRepositoriesForOrganization")]
public static async Task<List> GetAllRepositoriesForOrganization([ActivityTrigger] DurableActivityContext context)
{
// 从编配器function中获取组织的名称列表
var organizationName = context.GetInput();
// 调用API获取某个组织的存储库列表
var repositories = (await github.Repository.GetAllForOrg(organizationName)).Select(x => (x.Id, x.Name)).ToList();
return repositories;
}

请注意使用带有DurableActivityContext参数的ActivityTrigger属性:这是在将function限定为活动function。

接下来,你可以定义一个编配器function来获取一个组织的所有存储库,然后将每个存储库所有未解决的问题数量相加,并将结果存储在某处:

[FunctionName("Orchestrator")]
public static async Task RunOrchestrator(
    [OrchestrationTrigger] DurableOrchestrationContext context)
{
    // 通过Orchestrator_HttpStart function获取组织列表
    var organizationName = context.GetInput();
    // 通过Activity Function获取某个组织的存储库列表
    var repositories = await context.CallActivityAsync<List>("GetAllRepositoriesForOrganization", organizationName);

    // 创建一组任务用于保存每个function的结果
    var tasks = new Task[repositories.Count];
    for (int i = 0; i < repositories.Count; i++)
    {
        // 启动一个不带`async`的`GetOpenedIssues`活动
        // 这将同时启动另一个活动
        tasks[i] = context.CallActivityAsync("GetOpenedIssues", (repositories[i]));
    }

    // 等待所有的活动function执行结束
    await Task.WhenAll(tasks);

    // 获取活动Function的结果,并作为列表返回
    var openedIssues = tasks.Select(x => x.Result).ToList();

    // 将列表发送给另一个活动Function存储在Blob Storage中。
    await context.CallActivityAsync("SaveRepositories", openedIssues);

    return context.InstanceId;
}

在上面的示例中,请注意OrchestrationTrigger属性与DurableOrchestrationContext参数的使用,该参数将RunOrchestrator限定为编配器function。

有意思的是,context方法的调用就是Azure Functions。这意味着工作流执行将受益于Azure Functions的可伸缩性和可靠性。

你可以在 GitHub 上找到上述的工作流程,当然不要错过微软提供的教程的全部细节。

查看英文原文: Azure Orchestrators Simplify the Creation of Stateful Serverless Workflows


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK