发布到 Azure 事件网格的 Durable Functions

了解如何将业务流程生命周期事件(如已创建、已完成和失败)自动发布到自定义 Azure Event Grid 主题。 此功能适用于 DevOps 方案(蓝/绿部署)、高级监视和跟踪长时间运行的后台活动。

注释

本教程使用.NET示例,但概念和Azure CLI命令适用于Durable Functions支持的所有语言,包括 JavaScript、Python、Java 和 PowerShell。 有关特定于语言的设置,请参阅先决条件中首选语言的快速入门。

先决条件

在本指南中,你将设置从Durable Functions应用到Azure Event Grid的端到端事件发布。

  • 配置 Durable Functions publisher 应用,以在业务流程状态发生更改时自动将生命周期事件(已创建、正在运行、已完成、已失败、已终止)发布到事件网格自定义主题。
  • 创建一个事件网格自定义主题,作为中心枢纽,通过配置的托管标识中的凭据进行事件路由。
  • 使用事件网格触发器创建侦听器(订阅者)函数应用,以便从主题接收事件并处理事件。
  • 将项目部署到Azure,其中Durable Functions应用自动发布事件。
  • 验证事件网格处理已订阅函数的路由和传递。

验证Durable Functions扩展

在继续作之前,请验证项目中已安装兼容的Durable Functions扩展版本。 对于进程内模型,所需的最低版本为 2.7.0 ,对于独立辅助角色模型,为 1.1.0

以下示例演示如何验证和更新.NET项目的扩展。 对于其他语言,请查看 package.json (JavaScript)、requirements.txt (Python)、pom.xmlbuild.gradle (Java), 或 requirements.psd1 (PowerShell) 以获取Durable Functions扩展版本。

检查您的.csproj文件中是否包含Microsoft.Azure.Functions.Worker.Extensions.DurableTask版本 1.1.0 或更高版本:

<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.0" />

若要更新,请运行:

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.DurableTask --version 1.1.0

创建自定义事件网格主题

可以使用 Azure CLIPowerShell Azure 门户创建事件网格主题,以便从Durable Functions发送事件。

本指南使用Azure CLI。

创建资源组

使用 az group create 命令创建资源组。 选择支持事件网格的位置,并匹配要在其中部署资源的位置。

注释

目前,Azure 事件网格不支持所有区域。 有关支持哪些区域的信息,请参阅 Azure 事件网格概述

az group create --name <resource-group-name> --location <location>

启用事件网格资源提供程序

  1. 如果这是首次在 Azure 订阅中使用事件网格,则可能需要注册事件网格资源提供程序。 运行以下命令,注册提供程序:

    az provider register --namespace Microsoft.EventGrid
    
  2. 完成注册可能需要一些时间。 若要查看状态,请运行以下命令:

    az provider show --namespace Microsoft.EventGrid --query "registrationState"
    

    registrationStateRegistered 后,即可继续。

创建自定义主题

事件网格主题提供用户定义的终结点,可向该终结点发布事件。 在以下命令中将 <topic-name> 替换为您主题的唯一名称。 主题名称必须唯一,因为它将用作 DNS 条目。

az eventgrid topic create --name <topic-name> --location <location> --resource-group <resource-group-name>

获取主题终结点

获取主题的终结点。 将以下命令中的 <topic-name> 替换为您选择的名称。

az eventgrid topic show --name <topic-name> --resource-group <resource-group-name> --query "endpoint" --output tsv

保存此终结点供以后使用。

Azure 中的托管标识允许资源在不存储凭据、简化安全性和标识管理的情况下向 Azure 服务进行身份验证。 将与 Durable Function 应用关联的托管标识分配给事件网格自定义主题。

配置Durable Functions发布者应用

尽管Durable Functions应用会自动将业务流程生命周期事件发布到事件网格,但需要配置连接设置。 使用以下配置更新本地 host.json 文件以启用事件网格发布:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "default": "Information"
    }
  },
  "extensions": {
    "durableTask": {
      "tracing": {
        "traceInputsAndOutputs": false
      },
      "eventGridTopicEndpoint": "%EventGrid__topicEndpoint%",
      "eventGridKeySettingName": "EventGrid__credential"
    }
  }
}

注释

eventGridTopicEndpoint 设置引用前面保存的事件网格自定义主题终结点。 凭据设置可同时处理托管身份和连接字符串场景。

分配 EventGrid 数据发送者角色

授予 托管标识 将事件发布到 Event Grid 主题的权限。

az role assignment create \
  --assignee <client-id-of-managed-identity> \
  --assignee-principal-type ServicePrincipal \
  --role "EventGrid Data Sender" \
  --scope /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name>

请替换以下值:

  • <client-id-of-managed-identity>:用户分配的托管标识的客户端 ID
  • <subscription-id>:Azure订阅 ID
  • <resource-group-name>:包含事件网格主题的资源组的名称
  • <topic-name>:事件网格主题的名称

注释

角色分配可能需要 5-10 分钟才能传播。 如果在分配后马上进行操作,可能会看到身份验证错误。

配置应用设置

为函数应用和主题启用托管标识后,请在Durable Functions函数应用上配置事件网格应用设置。

添加以下应用设置:

  • EventGrid__topicEndpoint 将值用作事件网格主题终结点。
  • EventGrid__credential 具有值 managedidentity
  • 用户分配的托管标识客户端 ID 的值为 EventGrid__clientId
az functionapp config appsettings set --name <function app name> --resource-group <resource group name> --settings EventGrid__topicEndpoint="<topic endpoint>" EventGrid__credential="managedidentity" EventGrid__clientId="<client id>"

如果使用系统分配的托管标识

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

az functionapp config appsettings set --name <function app name> --resource-group <resource group name> --settings EventGrid__topicEndpoint="<topic endpoint>"

创建用于侦听事件的函数

创建一个新的函数应用来侦听持久化函数应用发布的事件。 侦听器函数应用必须与事件网格主题位于同一区域。

创建侦听器函数应用

  1. 为侦听器函数应用创建资源组。

    az group create --name <listener-resource-group-name> --location <location>
    
  2. 为侦听器函数应用创建存储帐户。

    az storage account create \
      --name <storage-account-name> \
      --resource-group <listener-resource-group-name> \
      --location <location> \
      --sku Standard_LRS \
      --allow-blob-public-access false
    
  3. 创建函数应用。

    az functionapp create \
      --resource-group <listener-resource-group-name> \
      --consumption-plan-location <location> \
      --runtime <preferred-runtime> \
      --runtime-version <runtime-version> \
      --functions-version 4 \
      --name <listener-function-app-name> \
      --storage-account <storage-account-name>
    

替换占位符的值:

  • <listener-resource-group-name>:侦听器资源组的名称
  • <location>:Azure区域(必须与事件网格主题区域匹配)
  • <storage-account-name>:存储帐户的全局唯一名称(仅 3-24 个字符、小写和数字)
  • <listener-function-app-name>:侦听器函数应用的全局唯一名称
  • <preferred-runtime>:项目的编程运行时。 例如,dotnet-isolated
  • <runtime-version>:正在使用的运行时版本。 例如,对于 dotnet-isolated 运行时,可以指定 8.0

在本地创建事件网格触发器函数

  1. 为侦听器函数项目创建本地目录:

    mkdir EventGridListenerFunction
    cd EventGridListenerFunction
    
  2. 使用首选语言初始化新的 Functions 项目。 以下示例使用 dotnet-isolated,但可以使用 nodepythonjavapowershell

    func init --name EventGridListener --runtime dotnet-isolated
    
  3. 创建新的事件网格触发器函数:

    func new --template "Event Grid trigger" --name EventGridTrigger
    
  4. 打开生成的事件网格触发器文件并查看代码。 该模板提供记录事件信息的基本实现。

将函数发布到Azure

将本地创建的函数发布到之前创建的侦听器函数应用:

func azure functionapp publish <listener-function-app-name>

使用 CLI 创建事件网格订阅

现在您可以创建事件网格订阅以将事件网格主题连接到您的侦听器函数。 有关详细信息,请参阅 Azure 事件网格中的概念

使用 azurefunction endpoint 类型创建 Event Grid 订阅,该 endpoint 类型会自动处理 Webhook 握手:

az eventgrid event-subscription create \
  --name <subscription-name> \
  --source-resource-id /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name> \
  --endpoint /subscriptions/<subscription-id>/resourceGroups/<listener-resource-group-name>/providers/Microsoft.Web/sites/<listener-function-app-name>/functions/EventGridTrigger \
  --endpoint-type azurefunction

替换占位符的值:

  • <subscription-name>:事件网格订阅的名称(例如 DurableFunctionsEventSub
  • <subscription-id>:Azure订阅 ID
  • <resource-group-name>:包含事件网格主题的资源组
  • <topic-name>:事件网格主题的名称
  • <listener-resource-group-name>:包含侦听器函数应用的资源组
  • <listener-function-app-name>:侦听器函数应用的名称

小窍门

建议将 --endpoint-type azurefunction 与函数的资源 ID 一起使用。 它能够自动处理 Webhook 的验证,比使用带有 URL 的 --endpoint-type webhook 更加可靠。

你现在准备好接收生命周期事件了。

部署并验证设置

部署Durable Functions应用

在运行端到端流之前,请确保将Durable Functions应用部署到Azure:

  1. 请在 Durable Functions 项目中将函数代码发布到 Azure。
  2. 通过在 Azure 门户中导航到函数应用并检查它是否显示“正在运行”状态来验证部署。

验证事件网格配置

在启动编排之前,请验证是否已正确配置事件网格的发布配置。

  1. 在Azure门户中,导航到事件网格自定义主题。
  2. 选择 “指标 ”并检查 已发布事件已删除事件 ,以验证主题是否可访问。
  3. 在Durable Functions函数应用程序中,验证应用程序设置是否显示在 Settings>环境变量下:
    • EventGrid__topicEndpoint 应设置
    • EventGrid__credential 应设置为 managedidentity (如果使用托管标识)

运行业务流程并监视事件

在验证设置后,触发编排并监视事件流。

  1. 在 Azure 门户中,导航到 Durable Functions 函数应用。

  2. 选择 Functions 并找到 HTTP 触发的编排启动函数(例如 HelloOrchestration_HttpStart)。

  3. 选择 “代码 + 测试 ”,然后选择“ 获取函数 URL”。

  4. 使用 HTTP 客户端(如 Postman 或 curl)将 POST 请求发送到函数 URL。 例如:

    curl -X POST https://<function_app_name>.chinacloudsites.cn/api/HelloOrchestration_HttpStart
    
  5. 编排开始,Durable Functions运行时将生命周期事件发布到事件网格。

验证侦听器函数中的事件

检查侦听器函数应用以确认它已收到事件:

  1. 在 Azure 门户中,导航到 listener 函数应用(事件网格触发器)。
  2. 选择事件网格触发器函数(例如 EventGridTrigger)。
  3. 选择 “监视器 ”以查看最近的执行。
  4. 选择执行以查看事件详细信息。

当侦听器函数处理编排生命周期事件时,您应会看到类似如下的输出:

2026-01-27T14:32:15.847 [Info] Event Grid trigger function processed an event.
2026-01-27T14:32:15.848 [Info] Event type: orchestratorEvent
2026-01-27T14:32:15.849 [Info] Event subject: durable/orchestrator/Running
2026-01-27T14:32:15.850 [Info] Event data: {"hubName":"DurableFunctionsHub","functionName":"HelloOrchestration","instanceId":"<your_instance_id>","reason":"","runtimeStatus":"Running"}
2026-01-27T14:32:32.114 [Info] Event Grid trigger function processed an event.
2026-01-27T14:32:32.115 [Info] Event type: orchestratorEvent
2026-01-27T14:32:32.116 [Info] Event subject: durable/orchestrator/Completed
2026-01-27T14:32:32.117 [Info] Event data: {"hubName":"DurableFunctionsHub","functionName":"HelloOrchestration","instanceId":"<your_instance_id>","reason":"","runtimeStatus":"Completed"}

在 Application Insights 中验证(可选)

更全面了解事件情况:

  1. 在 Azure 门户中,导航到 Durable Functions 函数应用。
  2. 从左侧菜单中选择 Application Insights
  3. 选择 “日志 ”并运行此 KQL 查询以查看所有已处理的事件:
    traces
    | where message contains "Event type" or message contains "Event subject"
    | project timestamp, message
    | order by timestamp desc
    

事件架构

当Durable Functions业务流程状态发生更改时,事件网格会发布具有以下结构的事件:

元数据 说明
id 事件网格事件的唯一标识符。
subject 事件主题的路径。 格式:durable/orchestrator/{orchestrationRuntimeStatus}。 状态可以是RunningCompletedFailedTerminated
data Durable Functions特定参数。
data.hubName TaskHub 名称。
data.functionName Orchestrator 函数名称。
data.instanceId Durable Functions 实例 ID。 此 ID 是每次编排执行的唯一 ID。
data.reason 与跟踪事件关联的其他数据。 有关详细信息,请参阅 Durable Functions(Azure Functions)中的诊断
data.runtimeStatus 编排运行时状态。 可能的值:RunningCompleted、、FailedCanceled
eventType 对于Durable Functions事件,始终为“orchestratorEvent”。
eventTime 事件时间(UTC)。
dataVersion 生命周期事件架构的版本。
metadataVersion 元数据的版本。
topic 事件网格主题资源标识符。

了解事件流

事件由Durable Functions 运行时在每个业务流程状态转换时自动发布。 无需添加代码即可发出事件 - 它们自动生成。 事件网格可确保向所有订阅者至少传递一次,因此,在极少数故障情况下,可能会收到重复事件。 请考虑根据需要添加 instanceId 去重逻辑。

故障排除

事件未发布到事件网格

问题:侦听器函数未接收事件。

解决方法

  • 验证Durable Functions函数应用是否具有正确的应用设置:
    • EventGrid__topicEndpoint 必须指向自定义主题终结点
    • EventGrid__credential 必须设置为 managedidentity
    • EventGrid__clientId 如果使用用户分配的标识,则必须设置
  • 验证托管标识是否具有分配给事件网格自定义主题的 EventGrid 数据发送者 角色。
  • 检查 Application Insights 中的Durable Functions函数应用日志是否存在错误。
  • 验证事件网格主题是否存在并且在同一订阅中可访问。

未触发监听器函数

问题:侦听器函数存在,但在发布事件时未执行。

解决方法

  • 验证是否已创建事件网格订阅并已启用:
    • 在 Azure 门户中,导航到事件网格主题 → Subscriptions
    • 确认侦听器函数的订阅状态 已列出为“已启用”
  • 验证事件网格订阅是否使用正确的终结点类型:
    • 对于 Azure Functions,请结合函数的资源 ID 使用 --endpoint-type azurefunction
    • 如果使用 --endpoint-type webhook,请确保 Webhook URL 格式正确: https://<function-app>.chinacloudsites.cn/runtime/webhooks/eventgrid?functionName=<function-name>&code=<system-key>
  • 检查侦听器函数应用日志中是否存在错误或传递问题。
  • 在事件网格主题→ 指标中,检查是否存在可能指示传递失败的 已删除事件

日志中的“禁止访问”或身份验证错误

问题:发布到事件网格时的身份验证错误。

解决方法

  • 验证托管身份是否已正确配置并在 Durable Functions 函数应用上启用:
    • 在 Azure 门户中,导航到函数应用 → Identity
    • 请确认“状态”显示为 开启,无论是系统分配标识还是用户分配标识。
  • 验证角色分配是否正确:
    • 导航到您的事件网格主题 → 访问控制(IAM)
    • 确认托管标识具备 EventGrid 数据发送方 角色(注意:“Event”和“Grid”之间无空格)
    • 角色分配可能需要 5-10 分钟才能生效

“连接被拒绝”或“找不到终结点”错误

问题:事件网格主题的连接错误。

解决方法

  • 验证应用设置中的事件网格主题终结点是否正确,并包含完整的 URL(例如) https://my-topic.eventgrid.chinacloudapi.cn/api/events
  • 验证同一订阅和区域中是否存在事件网格主题资源
  • 检查Durable Functions应用是否对事件网格终结点具有网络访问权限

在本地测试

若要在本地进行测试,请参阅 使用查看器 Web 应用的本地测试。 使用托管标识在本地测试时,请使用开发人员凭据对事件网格主题进行身份验证。 有关详细信息,请参阅 使用托管标识配置Durable Functions - 本地开发

清理资源

如果不打算继续使用本教程中创建的资源,请将其删除以避免产生费用。

删除资源组

删除资源组及其包含的所有资源:

az group delete --name <resource-group-name> --yes
az group delete --name <listener-resource-group-name> --yes

删除单个资源

如果要保留某些资源,可以单独删除它们:

  1. 删除事件网格订阅:

    az eventgrid event-subscription delete \
      --name <subscription-name> \
      --source-resource-id /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name>
    
  2. 删除事件网格主题:

    az eventgrid topic delete --name <topic-name> --resource-group <resource-group-name>
    
  3. 删除函数应用:

    az functionapp delete --name <publisher-function-app-name> --resource-group <resource-group-name>
    az functionapp delete --name <listener-function-app-name> --resource-group <listener-resource-group-name>
    
  4. 删除存储帐户:

    az storage account delete --name <storage-account-name> --resource-group <resource-group-name> --yes
    az storage account delete --name <listener-storage-account-name> --resource-group <listener-resource-group-name> --yes
    

后续步骤

了解有关以下方面的详细信息: