练习 - 使用 Durable Functions 创建工作流

已完成

在本练习中,你将使用上一单元中的示例方案了解如何使用 Durable Functions 在 Azure 门户中创建审批工作流。

创建函数应用

  1. 使用用于激活沙盒的同一帐户登录到 Azure 门户

  2. 在 Azure 门户菜单或 主页Azure 服务下,选择“ 创建资源”。 此时会显示“创建资源”窗格。

  3. 搜索并选择 Function App。 选择“消耗”,然后选择“选择”按钮。 此时将显示“创建函数应用”窗格。

  4. 在“基本信息”选项卡上,为每个设置输入以下值。

    设置 价值 DESCRIPTION
    项目详细信息
    订阅 Concierge 订阅 指定要在其下创建此新函数应用的订阅。
    资源组 从下拉列表中选择 [沙盒资源组名称] 指定要在其中创建函数应用的资源组的名称。 我们在激活沙盒时分配的沙盒资源组(即 [沙盒资源组名称])中创建函数应用。
    实例详细信息
    函数应用名称 [全局唯一名称] 指定名称以用于识别您的新函数应用程序。 有效字符为 a-z0-9-
    发布 代码 指定函数使用代码而不是容器。
    运行时堆栈 Node.js 指定本模块中的示例代码是用 JavaScript 编写的。
    版本 20 LTS 指定运行时堆栈的版本。
    区域 [从本节后面的列表中选择] 选择离你最近的区域,该区域也是以下允许的沙盒区域之一。
    操作系统
    操作系统 Windows 指定用于托管函数应用程序的操作系统。
    计划

    使用免费沙盒,可以在部分 Azure 全球区域中创建资源。 创建资源时,请从下面的列表中选择一个区域:

    • 西部美国 2
    • 美国中南部
    • 美国中部
    • 美国东部
    • 西欧
    • 东南亚
    • 日本东部
    • 巴西南部
    • 澳大利亚东南部
    • 印度中部
  5. 选择“下一页:存储”。

  6. 在“存储”选项卡上,为每个设置输入以下值。

    设置 价值 DESCRIPTION
    存储
    存储帐户 [全局唯一名称] 指定函数应用使用的新存储帐户的名称(不需要与为函数指定的全局唯一名称匹配)。 存储帐户名称必须为 3 到 24 个字符,并且只能包含数字和小写字母。 此对话框会自动使用动态生成的唯一名称填充字段。 但是,可以随意使用其他名称,甚至使用现有帐户。
  7. 选择“下一步: 网络”。 接受默认值。

  8. 选择 “下一步:监视”。

  9. 在“ 监视 ”选项卡上,输入设置的以下值。

    设置 价值 DESCRIPTION
    Application Insights
    启用 Application Insights 指定对此模块禁用 Application Insights。
  10. 选择 “查看 + 创建 ”并查看配置的选项。 如果对选项感到满意,请选择“ 创建 ”以预配和部署函数应用。

等待部署完成,然后继续。 部署可能需要几分钟时间。

安装 durable-functions npm 包

由于我们正在创建 JavaScript Durable Functions,因此需要安装 durable-functions npm 包。 为此,请执行以下步骤。

  1. 选择“转到资源”以选择函数应用。 系统将显示函数应用窗格。

  2. 在左侧菜单窗格中,在 “开发工具”下,选择 “应用服务编辑器”(预览),然后选择“ 打开编辑器”。 “应用服务编辑器快速启动”窗格显示在新的浏览器窗口中。

  3. 在左侧菜单窗格中,突出显示 WWWROOT 文件夹。

  4. 在左侧工具栏菜单中,选择 “打开控制台” 图标。

    此操作将启动控制台。 可以使用此控制台访问托管函数的 Web 服务器,并为函数编写代码。

  5. 创建新的 package.json 文件。

    • 在控制台中运行以下命令以创建新的 JSON 文件,并在编辑器中打开它。

      touch package.json
      open package.json
      
    • 添加以下代码。

      {
        "name": "example",
        "version": "1.0.0"
      }
      

      example 替换为包的名称。 例如,可以使用前面为函数指定的全局唯一名称。

  6. 选择 Ctrl+S 保存文件,然后按 Ctrl+Q 关闭文档。

  7. 切换回 Azure 门户。

  8. 在左侧菜单栏中的“开发工具”下,选择“控制台”。 此时将显示函数应用的“控制台”窗格。

  9. 运行下面的命令:

    npm install durable-functions
    

    此命令指示节点包管理器安装 durable-functions 包和任何必需的依赖项。 安装可能需要几分钟才能完成,节点包管理器可能会显示一些警告,你可以忽略这些警告。

    注释

    如果系统提示安装较新版本的 npm,请使用错误中提供的命令安装较新版本,然后在安装新版本后安装 durable-functions 包。

    等待所有包完成安装。

  10. 在左侧菜单窗格中,向上滚动并选择“ 概述”,然后在顶部菜单栏中选择“ 重启”,然后在系统提示重启时选择“ ”。

    等待重启过程完成,然后继续。

创建用于提交设计建议的客户端函数

  1. 在 Azure 门户菜单或 主页 的“ 最近使用的资源”下,选择“ 查看所有”,然后选择函数应用。 系统将显示函数应用窗格。

  2. 在“概述”页上,选择屏幕中心内的 “函数 ”选项卡。

  3. 选择 “在 Azure 门户中创建 ”按钮。 此时将显示“创建函数”窗格。

  4. 选择模板下的筛选器框中,输入Durable Functions HTTP 启动程序并从列表中选择该模板。 此模板创建一个持久函数,用于响应 HTTP 请求。

  5. “模板详细信息”下,对于 “新建函数 ”字段,输入 HttpStart 以获取函数的名称,然后在 “授权”级别 字段中选择“ 函数”,然后选择“ 创建”。 此时将显示函数的“HttpStart”窗格。

  6. 在左侧菜单窗格的“开发人员”下,选择“代码 + 测试”。 此时,函数的“代码和测试”窗格显示。

    此时将在编辑器中显示 index.js 文件的代码。 文件应与下面的示例类似:

    const df = require("durable-functions");
    
    module.exports = async function (context, req) {
        const client = df.getClient(context);
        const instanceId = await client.startNew(req.params.functionName, undefined, req.body);
    
        context.log(`Started orchestration with ID = '${instanceId}'.`);
    
        return client.createCheckStatusResponse(context.bindingData.req, instanceId);
    };
    
  7. 在函数中文件的下拉列表中,选择 function.json 以查看与新函数关联的绑定。 此信息指定任何身份验证要求,以及可以触发函数的 HTTP 方法。 此文件还指定函数是启动业务流程进程的客户端。 文件应与下面的示例类似:

    {
      "bindings": [
        {
          "authLevel": "function",
          "name": "req",
          "type": "httpTrigger",
          "direction": "in",
          "route": "orchestrators/{functionName}",
          "methods": [
            "post",
            "get"
          ]
        },
        {
          "name": "$return",
          "type": "http",
          "direction": "out"
        },
        {
          "name": "starter",
          "type": "orchestrationClient",
          "direction": "in"
        }
      ]
    }
    

    注释

    绑定将资源和其他项与触发器相关联。 它是一种声明性机制,无需对代码中的其他服务和函数进行硬编码引用。

创建协调器函数

  1. 在 Azure 门户菜单或 主页 的“ 最近使用的资源”下,选择“ 查看所有”,然后选择函数应用。 系统将显示函数应用窗格。

  2. “概述 ”页上,选择屏幕中心内的 “函数 ”选项卡。

  3. “函数 ”菜单栏中,选择“ 创建”。 此时将显示“创建函数”窗格。

  4. “选择模板”下的 “筛选器 ”框中,输入 Durable Functions 业务流程协调程序 并从列表中选择该模板。 此模板创建一个持久函数,用于协调函数的执行。

  5. “模板详细信息”下,对于 “新建函数 ”字段,输入 OrchFunction 以获取函数的名称,然后选择“ 创建”。 此时将显示“OrchFunction”函数窗格。

  6. 在左侧菜单窗格的“开发人员”下,选择“代码 + 测试”。 此时,函数的“代码和测试”窗格显示。

    此时将在编辑器中显示 index.js 文件的代码。

  7. 将现有代码替换为以下代码。

    const df = require("durable-functions");
    
    module.exports = df.orchestrator(function* (context) {
        const outputs = [];
    
        /*
        * We will call the approval activity with a reject and an approved to simulate both
        */
    
        outputs.push(yield context.df.callActivity("Approval", "Approved"));
        outputs.push(yield context.df.callActivity("Approval", "Rejected"));
    
        return outputs;
    });
    

    此代码将调用一个名为 “审批” 的活动函数,你将很快创建该函数。 业务流程协调程序函数中的代码调用 审批 函数两次。 第一次模拟接受该建议,第二次测试建议拒绝逻辑。

    每个调用返回的值合并并传回客户端函数。 在生产环境中,业务流程函数将调用一系列活动函数来做出接受/拒绝决策,并返回这些活动的结果。

  8. 在顶部菜单栏中,选择“保存”以保存新函数。

创建活动函数

  1. 在 Azure 门户菜单或 主页 的“ 最近使用的资源”下,选择“ 查看所有”,然后选择函数应用。 系统将显示函数应用窗格。

  2. “概述 ”页上,选择屏幕中心内的 “函数 ”选项卡。

  3. “函数 ”菜单栏中,选择“ 创建”。 此时将显示“创建函数”窗格。

  4. 在“选择模板”下的“筛选器”框中,输入“Durable Functions activity”,然后从列表中选择该模板。 此模板创建一个持久函数,该函数在业务流程协调程序函数调用活动时运行。

  5. “模板详细信息”下,对于 “新建函数 ”字段,输入函数名称的 审批 ,然后选择“ 创建”。 此时会显示函数应用的 “审批 ”窗格。

  6. 在左侧菜单窗格的“开发人员”下,选择“代码 + 测试”。 此时,函数的“代码和测试”窗格显示。

    此时将在编辑器中显示 index.js 文件的代码。

  7. 将现有代码替换为以下代码。

    module.exports = async function (context) {
        return `Your project design proposal has been -  ${context.bindings.name}!`;
    };
    

    此函数返回一条消息,指示建议的状态。 context.bindings.name表达式要么是Accepted,要么是Rejected,具体取决于从协调器传递给函数的参数。 在实际场景中,你将在此函数中添加处理接受或拒绝操作的逻辑。

  8. 在顶部菜单栏中,选择“保存”以保存新函数。

确认 Durable Functions 工作流启动

  1. 在 Azure 门户菜单或 主页 的“ 最近使用的资源”下,选择“ 查看所有”,然后选择函数应用。 系统将显示函数应用窗格。

  2. 选择页面中心内的 “函数 ”选项卡。

  3. 选择 HttpStart 函数。 此时将显示函数的“HttpStart”窗格。

  4. 在顶部菜单栏中,选择“ 获取函数 URL ”并复制 URL。 URL 应与下面的示例类似:

    https://example.azurewebsites.net/api/orchestrators/{functionName}?code=AbCdEfGhIjKlMnOpQrStUvWxYz==
    

    您使用此 URL 来运行您的函数。

  5. 打开新的浏览器窗口,并转到复制的 URL。 在 URL 中,将 {functionName} 占位符替换为 OrchFunction,这应类似于以下示例:

    https://example.azurewebsites.net/api/orchestrators/OrchFunction?code=AbCdEfGhIjKlMnOpQrStUvWxYz==
    

    响应消息包含一组 URI 终结点,这些终结点可以用来监视并管理执行,该执行应与以下示例类似:

    {
      "id": "f0e1d2c3b4a5968778695a4b3c2d1e0f",
      "statusQueryGetUri": "https://example.azurewebsites.net/...",
      "sendEventPostUri": "https://example.azurewebsites.net/...",
      "terminatePostUri": "https://example.azurewebsites.net/...",
      "rewindPostUri": "https://example.azurewebsites.net/...",
      "purgeHistoryDeleteUri": "https://example.azurewebsites.net/..."
    }
    
  6. 复制 statusQueryGetUri 值,并使用 Web 浏览器转到此 URL。 应会看到类似于以下示例的响应消息:

    {
      "name": "OrchFunction",
      "instanceId": "f0e1d2c3b4a5968778695a4b3c2d1e0f",
      "runtimeStatus": "Completed",
      "input": null,
      "customStatus": null,
      "output": [
        "Your project design proposal has been -  Approved!",
        "Your project design proposal has been -  Rejected!"
      ],
      "createdTime": "2019-04-16T15:23:03Z",
      "lastUpdatedTime": "2019-04-16T15:23:35Z"
    }
    

    回想一下,协调函数会运行活动函数两次。 当首次触发时,活动函数表明项目建议被接受。 第二次拒绝该提案。 业务流程函数将这两个函数调用中的消息组合在一起,并将其返回到客户端函数。