You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

当Azure Durable Function实例表状态为Failed时,如何触发函数写入Azure SQL DB

实现Durable Function失败状态触发SQL写入的方案

方案一:在Durable编排流程内主动发送失败消息到队列(推荐)

这种方式不需要依赖存储表监听,直接在编排函数中捕获失败,将数据发送到队列,再由队列触发函数写入SQL,实时性和可靠性更优。

步骤1:在编排函数中捕获失败并调用辅助Activity发送队列消息

编排函数本身无法直接使用队列输出绑定,需封装专门的Activity函数处理队列消息发送:

[FunctionName("MyOrchestrator")]
public static async Task RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    try
    {
        // 执行你的业务Activity逻辑
        await context.CallActivityAsync("YourBusinessActivity", null);
    }
    catch (Exception ex)
    {
        // 构造包含失败详情的消息对象
        var failureDetails = new
        {
            InstanceId = context.InstanceId,
            RuntimeStatus = "Failed",
            FailureReason = ex.Message,
            OccurredAt = DateTime.UtcNow
        };

        // 调用Activity发送队列消息
        await context.CallActivityAsync("SendFailureToQueue", failureDetails);
    }
}

[FunctionName("SendFailureToQueue")]
public static void SendFailureToQueue(
    [ActivityTrigger] dynamic failureDetails,
    [Queue("durable-failure-events")] ICollector<string> queueCollector)
{
    // 将消息序列化为JSON字符串存入队列
    string jsonMsg = JsonConvert.SerializeObject(failureDetails);
    queueCollector.Add(jsonMsg);
}

步骤2:创建队列触发函数写入Azure SQL DB

用QueueTrigger绑定目标队列,读取消息后直接插入SQL:

[FunctionName("WriteFailureToSql")]
public static void Run(
    [QueueTrigger("durable-failure-events")] string queueMsg,
    [Sql("INSERT INTO DurableFunctionFailures (InstanceId, RuntimeStatus, FailureReason, OccurredAt) VALUES (@InstanceId, @RuntimeStatus, @FailureReason, @OccurredAt)", 
        ConnectionStringSetting = "AzureSqlConnection")] out dynamic sqlData)
{
    // 反序列化队列消息
    var failureData = JsonConvert.DeserializeObject<dynamic>(queueMsg);
    
    // 构造SQL插入数据
    sqlData = new
    {
        InstanceId = failureData.InstanceId,
        RuntimeStatus = failureData.RuntimeStatus,
        FailureReason = failureData.FailureReason,
        OccurredAt = failureData.OccurredAt
    };
}

方案二:监听Durable实例表的失败状态(适合无法修改现有编排代码的场景)

如果不能改动现有Durable编排逻辑,可使用Table触发器监听默认实例表(表名默认是DurableFunctionsHubInstances),过滤出状态为Failed的实体。

实现代码

[FunctionName("MonitorDurableFailuresFromTable")]
public static void Run(
    [TableTrigger("DurableFunctionsHubInstances", Filter = "RuntimeStatus eq 'Failed'")] DurableInstanceEntity tableEntity,
    [Sql("INSERT INTO DurableFunctionFailures (InstanceId, RuntimeStatus, FailureReason, OccurredAt) VALUES (@InstanceId, @RuntimeStatus, @FailureReason, @OccurredAt)", 
        ConnectionStringSetting = "AzureSqlConnection")] out dynamic sqlData)
{
    // 从表实体提取数据(Durable实例表的RowKey即为InstanceId)
    sqlData = new
    {
        InstanceId = tableEntity.RowKey,
        RuntimeStatus = tableEntity.RuntimeStatus,
        FailureReason = tableEntity.Output, // 失败详情通常存于Output字段
        OccurredAt = tableEntity.Timestamp
    };
}

// 对应Durable实例表的实体类
public class DurableInstanceEntity
{
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTime Timestamp { get; set; }
    public string RuntimeStatus { get; set; }
    public string Output { get; set; }
}

注意事项

  • Table触发器为轮询模式,默认间隔1分钟,存在一定延迟;可在host.json中调整轮询频率,但过于频繁会增加存储成本。
  • 需确保函数拥有存储表的读取权限,建议使用系统分配的托管身份授权。

通用注意点

  • 幂等性处理:SQL插入时建议给InstanceId添加唯一性约束,避免重复写入相同失败记录。
  • 连接配置:将存储账户和SQL DB的连接字符串添加到Function App的应用设置中,禁止硬编码。
  • 消息序列化:确保队列消息的序列化/反序列化逻辑一致,避免解析错误。

内容的提问来源于stack exchange,提问作者Sri Azure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:20:01