Compartir a través de

从 Durable Functions 发布到 Azure 事件网格

本文介绍了如何设置 Durable Functions,以便将业务流程生命周期事件(例如“已创建”、“已完成”和“失败”)发布到自定义的 Azure 事件网格主题

此功能在以下场景中非常有用:

  • 蓝/绿部署等 DevOps 场景:在实施并列部署策略之前,你可能想要了解是否有任何任务正在运行。

  • 高级监视和诊断支持:可以在已针对查询优化的外部存储(例如 Azure SQL 数据库或 Azure Cosmos DB)中跟踪业务流程状态信息。

  • 长时间运行的后台活动:如果对长时间运行的后台活动使用 Durable Functions,此功能有助于了解当前状态。

先决条件

创建自定义事件网格主题

创建事件网格主题,以便从 Durable Functions 发送事件。 以下说明介绍如何使用 Azure CLI 创建主题。 也可以使用 PowerShell使用 Azure 门户来创建主题。

创建资源组

使用 az group create 命令创建资源组。 目前,Azure 事件网格不支持所有区域。 有关支持哪些区域的信息,请参阅 Azure 事件网格概述

az group create --name eventResourceGroup --location chinanorth2

创建自定义主题

事件网格主题提供用户定义的终结点,可向该终结点发布事件。 用主题的唯一名称替换 <topic_name>。 主题名称必须唯一,因为它将用作 DNS 条目。

az eventgrid topic create --name <topic_name> -l chinanorth2 -g eventResourceGroup

获取终结点和密钥

获取主题的终结点。 将 <topic_name> 替换为所选的名称。

az eventgrid topic show --name <topic_name> -g eventResourceGroup --query "endpoint" --output tsv

如果使用基于密钥的身份验证,请获取主题密钥。 将 <topic_name> 替换为所选的名称。

az eventgrid topic key list --name <topic_name> -g eventResourceGroup --query "key1" --output tsv

现在,可将事件发送到主题。

使用基于密钥的身份验证配置事件网格发布

在 Durable Functions 项目中,找到 host.json 文件。

Durable Functions 1.x

eventGridTopicEndpoint 属性中添加 eventGridKeySettingNamedurableTask

{
  "durableTask": {
    "eventGridTopicEndpoint": "https://<topic_name>.chinanorth2-1.eventgrid.chinacloudapi.cn/api/events",
    "eventGridKeySettingName": "EventGridKey"
  }
}

Durable Functions 2.x

在文件的 notifications 属性中添加 durableTask 部分,并将 <topic_name> 替换为所选的名称。 如果 durableTaskextensions 属性不存在,请像下面的示例一样创建它们:

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "notifications": {
        "eventGrid": {
          "topicEndpoint": "https://<topic_name>.chinanorth2-1.eventgrid.chinacloudapi.cn/api/events",
          "keySettingName": "EventGridKey"
        }
      }
    }
  }
}

可能的 Azure 事件网格配置属性可以在 host.json 文档中找到。 配置 host.json 文件后,函数应用会将生命周期事件发送到事件网格主题。 同时在本地和 Azure 中运行函数应用时,将启动此操作。

在函数应用和 local.settings.json 中设置主题密钥的应用设置。 以下 JSON 是使用 Azure 存储模拟器用于本地调试的 local.settings.json 示例。 将 <topic_key> 替换为主题密钥。

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "EventGridKey": "<topic_key>"
    }
}

如果使用存储模拟器而不是实际 Azure 存储帐户,请确保它正在运行。 建议在执行之前清除任何现有存储数据。

如果使用的是实际 Azure 存储帐户,请将 UseDevelopmentStorage=true 中的 local.settings.json 替换为其连接字符串。

使用托管标识配置事件网格发布

Azure 中的托管标识允许资源在不存储凭据、简化安全性和标识管理的情况下向 Azure 服务进行身份验证。 在 Azure 资源上启用系统分配的托管标识并绑定到该资源的生命周期时,系统分配的托管标识会自动创建。 如果删除资源,则标识也会被删除。 用户分配的 托管标识是作为独立的 Azure 资源创建的,可以分配给多个资源。 它独立于所有资源存在,从而为共享访问和集中式身份管理提供灵活性。 建议使用用户分配的身份,因为它不会附加到应用程序的生命周期中。

有关详细信息,请访问 使用应用服务和 Azure Functions 的托管标识

系统分配的标识

若要配置系统分配的标识,请按照以下说明作:

配置

  1. 为函数应用启用系统分配的标识

    • 转到函数应用的 “标识 ”部分,在 “系统分配 ”选项卡中,将 “状态 ”开关切换为“打开”。

      在函数应用中启用系统分配标识的屏幕截图。

  2. 在事件网格主题资源中,为函数应用提供 EventGrid 数据发送者角色。

    • 转到 “访问控制”(IAM) 部分,单击“ + 添加”。

      将角色添加到事件网格主题资源的屏幕截图。

    • 选择 EventGrid 数据发送方 角色,单击“ 下一步”。

      选择 EventGrid 数据发送方角色的屏幕截图。

    • 在“分配访问权限”部分中选择“托管标识”,单击“成员”部分中的“+ 选择成员”,选择托管标识,然后单击“查看 + 分配”。

      选择托管标识的屏幕截图。

应用设置

添加一个 EventGrid__topicEndpoint 应用设置,该值作为事件网格主题终结点。

可以使用以下命令: az functionapp config appsettings set --name <function app name> --resource-group <resource group name> --settings EventGrid__topicEndpoint="<topic endpoint>"

用户分配的标识

若要配置用户分配的托管标识,请按照以下说明作:

配置

  1. 创建用户分配的托管标识。

    • 在 Azure 门户中,在全局搜索栏中搜索 托管身份

    • 创建用户分配的托管标识(UAMI),然后选择 “查看 + 创建”。

      创建用户分配的托管标识的屏幕截图。

  2. 将 UAMI 关联到函数应用资源

    • 转到函数应用“ 标识 ”部分,单击“ 添加 +”。

      用户分配的托管标识的函数应用标识部分的屏幕截图。

    • 选择上面创建的 UAMI,然后单击“ 添加”。

      选择特定用户分配的托管标识的屏幕截图。

  3. 将 UAMI 附加到事件网格主题资源。

    • 转到事件网格主题资源“ 标识 ”部分,选择 “用户分配 ”选项卡,然后单击“ 添加 +”。 选择用户分配的托管标识,然后单击“ 添加”。

      将用户分配的托管标识添加到事件网格主题的屏幕截图。

  4. 创建事件网格订阅并选择终结点。

    • 在事件网格主题资源的“ 概述 ”选项卡中,选择“ + 事件订阅”,然后创建事件订阅。

      “+ 事件订阅”按钮的屏幕截图。

    • 根据在 “终结点详细信息”中选择的终结点,你将看到“ 用于传递的托管标识 ”部分。 选择为托管标识类型分配的用户,然后选择 UAMI。

      将用户分配的托管标识添加到事件网格订阅的屏幕截图。

  5. 在事件网格主题资源中,将 EventGrid 数据发送者 角色分配给 UAMI。

    • 转到 “访问控制”(IAM) 部分,单击“ + 添加”。

      将角色添加到事件网格主题资源的屏幕截图。

    • 选择 EventGrid 数据发送方 角色,单击“ 下一步”。

      选择 EventGrid 数据发送方角色的屏幕截图。

    • 在“分配访问权限到”部分选择“托管身份”,在“成员”部分点击“+ 选择成员”,选择“UAMI”,然后单击“审阅 + 分配”。

      选择托管标识的屏幕截图。

应用设置

  • 添加一个 EventGrid__topicEndpoint 应用设置,该值作为事件网格主题终结点。
  • 添加一个值为EventGrid__credential的应用设置managedidentity
  • 添加一个 EventGrid__clientId 应用设置,其中包含用户分配的托管标识客户端 ID 的值。

创建用于侦听事件的函数

使用 Azure 门户,创建另一个函数应用来侦听 Durable Functions 应用发布的事件。 最好是将该应用放置在事件网格主题所在的同一区域。

创建事件网格触发器函数

  1. 在函数应用中,选择“函数”,然后选择“+ 添加”

    在 Azure 门户中添加函数。

  2. 搜索“事件网格”,然后选择“Azure 事件网格触发器”模板。

    在 Azure 门户中选择事件网格触发器模板。

  3. 为新触发器命名,然后选择“创建函数”

    在 Azure 门户中为事件网格触发器命名。

    创建包含以下代码的函数:

    #r "Newtonsoft.Json"
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using Microsoft.Extensions.Logging;
    
    public static void Run(JObject eventGridEvent, ILogger log)
    {
        log.LogInformation(eventGridEvent.ToString(Formatting.Indented));
    }
    

添加事件网格订阅

现在可以为创建的事件网格主题添加事件网格订阅。 有关详细信息,请参阅 Azure 事件网格中的概念

  1. 在新函数中,选择“集成”,然后选择“事件网格触发器(eventGridEvent)”

    选择“事件网格触发器”链接。

  2. 选择“创建事件网格描述”

    创建事件网格订阅。

  3. 为事件订阅命名,并选择“事件网格主题”主题类型。

  4. 选择订阅。 然后,选择为事件网格主题创建的资源组和资源。

  5. 选择“创建” 。

    创建事件网格订阅。

现已准备好接收生命周期事件。

运行 Durable Functions 应用以发送事件

在前面配置的 Durable Functions 项目中,开始在本地计算机上调试并启动业务流程。 该应用将 Durable Functions 生命周期事件发布到事件网格。 通过检查 Azure 门户中的事件网格日志,验证事件网格是否触发了所创建的侦听器函数。

2019-04-20T09:28:21.041 [Info] Function started (Id=3301c3ef-625f-40ce-ad4c-9ba2916b162d)
2019-04-20T09:28:21.104 [Info] {
    "id": "054fe385-c017-4ce3-b38a-052ac970c39d",
    "subject": "durable/orchestrator/Running",
    "data": {
        "hubName": "DurableFunctionsHub",
        "functionName": "Sample",
        "instanceId": "055d045b1c8a415b94f7671d8df693a6",
        "reason": "",
        "runtimeStatus": "Running"
    },
    "eventType": "orchestratorEvent",
    "eventTime": "2019-04-20T09:28:19.6492068Z",
    "dataVersion": "1.0",
    "metadataVersion": "1",
    "topic": "/subscriptions/<your_subscription_id>/resourceGroups/eventResourceGroup/providers/Microsoft.EventGrid/topics/durableTopic"
}

2019-04-20T09:28:21.104 [Info] Function completed (Success, Id=3301c3ef-625f-40ce-ad4c-9ba2916b162d, Duration=65ms)
2019-04-20T09:28:37.098 [Info] Function started (Id=36fadea5-198b-4345-bb8e-2837febb89a2)
2019-04-20T09:28:37.098 [Info] {
    "id": "8cf17246-fa9c-4dad-b32a-5a868104f17b",
    "subject": "durable/orchestrator/Completed",
    "data": {
        "hubName": "DurableFunctionsHub",
        "functionName": "Sample",
        "instanceId": "055d045b1c8a415b94f7671d8df693a6",
        "reason": "",
        "runtimeStatus": "Completed"
    },
    "eventType": "orchestratorEvent",
    "eventTime": "2019-04-20T09:28:36.5061317Z",
    "dataVersion": "1.0",
    "metadataVersion": "1",
    "topic": "/subscriptions/<your_subscription_id>/resourceGroups/eventResourceGroup/providers/Microsoft.EventGrid/topics/durableTopic"
}
2019-04-20T09:28:37.098 [Info] Function completed (Success, Id=36fadea5-198b-4345-bb8e-2837febb89a2, Duration=0ms)

事件架构

以下列表解释了生命周期事件架构:

  • id :事件网格事件的唯一标识符。
  • subject :事件主题的路径。 durable/orchestrator/{orchestrationRuntimeStatus}{orchestrationRuntimeStatus}RunningCompletedFailedTerminated
  • data :Durable Functions 特定的参数。
    • hubName任务中心名称。
    • functionName :业务流程协调程序函数名称。
    • instanceId :Durable Functions instanceId。
    • reason :与跟踪事件关联的其他数据。 有关详细信息,请参阅 Durable Functions 中的诊断 (Azure Functions)
    • runtimeStatus :业务流程运行时状态。 值为 Running、Completed、Failed 和 Canceled。
  • eventType :“orchestratorEvent”
  • eventTime :事件时间 (UTC)。
  • dataVersion :生命周期事件架构的版本。
  • metadataVersion:元数据的版本。
  • topic:事件网格主题资源。

如何在本地测试

若要进行本地测试,请阅读使用查看器 Web 应用进行本地测试

后续步骤