.NET 9 Durable Functions 中的异步 HTTP API 模式

作者:微信公众号:【架构师老卢】
9-25 20:9
115

.NET 9 中的 Azure Durable Functions 支持在无服务器体系结构中创建有状态工作流。异步 HTTP API 模式是处理通过 HTTP 触发的长时间运行操作的最有效模式之一。此模式非常适合允许客户端启动长时间运行的进程,然后轮询状态或结果。

在本指南中,我们将介绍使用 .NET 9 实现异步 HTTP API 模式,包括完整的项目设置、代码示例、配置文件,以及何时在实际场景中使用或避免使用此模式。

先决条件

  • .NET 9 开发工具包
  • Azure Functions Core Tools (v4)
  • Azure 存储帐户
  • Visual Studio 2022(17.8 或更高版本)或 Visual Studio Code

异步 HTTP API 模式概述

异步 HTTP API 模式旨在处理通过 HTTP 触发的长时间运行的操作。客户端发送请求以启动进程,服务器使用状态 URL 进行响应。然后,客户端可以轮询此 URL 以检查进度或检索最终结果。

实际用例

Report Generation System:生成复杂财务报告的业务应用程序,可能需要几分钟才能完成。客户端通过 HTTP 请求启动报告生成,然后在报告准备就绪后轮询状态终端节点以检索报告。

.NET 9 中的分步实现

项目结构

以下是为异步 HTTP API 示例定制的项目结构:

ReportGeneration  
│  
├── FunctionApp/  
│   ├── Orchestrator/  
│   │   └── ReportGenerationOrchestrator.cs  
│   ├── Activities/  
│   │   └── GenerateReportActivity.cs  
│   ├── HttpStart/  
│   │   └── HttpStartFunction.cs  
│   ├── host.json  
│   ├── local.settings.json  
│   └── function.json files (for each function)  
│  
├── Models/  
│   ├── ReportRequest.cs  
│   └── ReportResult.cs  
│  
└── ReportGeneration.csproj

1. 定义模型

这些模型有助于在 HTTP 触发器、业务流程协调程序和活动函数之间传递数据。

ReportRequest.cs

public class ReportRequest  
{  
    public string ReportType { get; set; }  
    public string CustomerId { get; set; }  
}

ReportResult.cs

public class ReportResult  
{  
    public string ReportUrl { get; set; }  
    public string Status { get; set; }  
}

2. 创建 Orchestrator 函数

业务流程协调程序函数管理工作流并调用 activity 函数以生成报告。

ReportGenerationOrchestrator.cs

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
public class ReportGenerationOrchestrator
{
    [Function("ReportGenerationOrchestrator")]
    public async Task<ReportResult> RunOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
    {
        var reportRequest = context.GetInput<ReportRequest>();
        // Call the activity function to generate the report
        var reportUrl = await context.CallActivityAsync<string>("GenerateReportActivity", reportRequest);
        // Return the result
        return new ReportResult
        {
            ReportUrl = reportUrl,
            Status = "Completed"
        };
    }
}

3. 实现 Activity 函数

activity 函数执行报告生成。

GenerateReportActivity.cs

using Microsoft.Azure.Functions.Worker;
public class GenerateReportActivity
{
    [Function("GenerateReportActivity")]
    public string Run([ActivityTrigger] ReportRequest reportRequest)
    {
        // Simulate report generation (replace with actual logic)
        return $"https://example.com/reports/{reportRequest.CustomerId}-{reportRequest.ReportType}.pdf";
    }
}

4. 创建 HTTP Start 函数

HTTP 启动函数启动编排并提供状态 URL。

HttpStartFunction.cs

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using System.Net;
public class HttpStartFunction
{
    [Function("HttpStartFunction")]
    public async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = "start-report-generation")] HttpRequestData req,
        [DurableClient] IDurableOrchestrationClient client)
    {
        var reportRequest = await req.ReadFromJsonAsync<ReportRequest>();
        // Start the orchestrator
        string instanceId = await client.StartNewAsync("ReportGenerationOrchestrator", reportRequest);
        // Create the status response
        var response = client.CreateCheckStatusResponse(req, instanceId);
        response.StatusCode = HttpStatusCode.Accepted;
        return response;
    }
}

5. 配置文件

host.json

{  
  "version": "2.0",  
  "logging": {  
    "applicationInsights": {  
      "samplingSettings": {  
        "isEnabled": true  
      }  
    }  
  }  
}

local.settings.json

{  
  "IsEncrypted": false,  
  "Values": {  
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",  
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"  
  }  
}

Orchestrator function.json示例

{  
  "bindings": [  
    {  
      "type": "orchestrationTrigger",  
      "direction": "in",  
      "name": "context"  
    }  
  ]  
}

对于 ,请创建一个 :GenerateReportActivityfunction.json

{  
  "bindings": [  
    {  
      "type": "activityTrigger",  
      "direction": "in",  
      "name": "input"  
    }  
  ]  
}

6. 工程文件配置

ReportGeneration.csproj

<Project Sdk="Microsoft.NET.Sdk.Worker">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.11.0" OutputItemType="Analyzer" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="2.9.1" />
    <PackageReference Include="Microsoft.DurableTask.AzureFunctions.Isolated" Version="1.0.0-beta" />
  </ItemGroup>
</Project>

测试异步 HTTP API 模式

  1. 启动 Azure 存储模拟器或使用实际的 Azure 存储帐户。
  2. 使用命令行运行函数应用。func start
  3. 使用像 Postman 这样的 HTTP 客户端发起 POST 请求,其中包含以下 JSON 正文:https://localhost:7071/api/start-report-generation{ "ReportType": "Sales", "CustomerId": "12345" }
  4. 您将收到一个状态 URL,您可以轮询该 URL 以检查进度或获取最终报告 URL。

何时使用和何时不使用异步 HTTP API 模式

适用情形

  1. 长时间运行的操作: 当任务需要相当长的时间时,例如生成复杂报表、执行数据迁移或处理大型数据集。
  2. 客户端轮询: 当客户端需要启动任务并定期检查其状态时。
  3. 避免超时: 在您希望避免 HTTP 超时的情况下,该模式允许客户端接收状态 URL 并稍后再检查。

何时不使用

  1. 短时间运行的任务: 如果预计任务会在几秒钟内完成,则最好同步处理。
  2. 实时要求: 当需要实时结果时,此模式可能会因轮询间隔而引入延迟。
  3. 低延迟场景: 如果需要即时反馈,请考虑使用其他模式或直接函数调用。

异步 HTTP API 模式是一个强大的解决方案,用于以可扩展且高效的方式处理通过 HTTP 触发的长时间运行的操作。通过实施此模式,您可以允许客户端启动流程,而无需等待它们完成,从而无缝处理复杂的工作流。

本指南提供了使用 .NET 9 Durable Functions 实现此模式的完整步骤,确保您能够很好地处理需要通过 HTTP 进行异步处理的实际方案。

相关留言评论
昵称:
邮箱:
阅读排行