Lambda Durable Functions:构建运行一年之久的工作流

发布: (2026年1月13日 GMT+8 14:50)
11 分钟阅读
原文: Dev.to

I’m happy to translate the article for you, but I’ll need the text you’d like translated. Could you please paste the content (or the portion you want translated) here? I’ll keep the source link unchanged at the top and preserve all formatting, markdown, and technical terms as requested.

我们一直在忽视的问题

想想你上一次构建多步骤工作流的时候:

  • 一个等待付款确认的订单处理系统。
  • 一个包含人工审核步骤的内容审核流水线。
  • 一个处理用户全天上传文件的数据管道。

你大概都会选择 Step Functions,对吧?我也是——直到我看到账单。

Step Functions 按状态转换计费。
每百万次转换 25 美元听起来很便宜,但一个六状态的审批工作流会在每一次运行时都产生费用,即使它只是在等人点击邮件中的“批准”。

💡 等待的真实成本

工作流每次运行的转换次数每月运行次数每月费用
审批(8 次转换)810 000$2.00

你在为那些仅仅是等待的状态付费。Lambda Durable Functions?等待时间为 $0.00

Lambda 持久函数到底是什么?

Lambda Durable Functions 让你可以像写普通代码一样编写长时间运行的工作流——无需 JSON 状态机。使用普通的 TypeScriptPython 编写,AWS 负责:

  • 编排
  • 状态持久化
  • 暂停后的恢复

魔法就在 await 语句中。当你的函数等待一个持久任务时,AWS:

  1. 检查点函数的状态。
  2. 关闭函数。
  3. 恢复函数,当任务完成时——无论是 5 秒后还是 5 个月后。

无需为等待付费

Lambda 持久函数工作原理

flowchart TD
    A[Function Starts] --> B[Execute Code]
    B --> C{Await Durable Task?}
    C -- Yes --> D[Checkpoint State]
    D --> E[Suspend Function]
    E --> F[Wait for Event/Timer]
    F --> G[Restore State]
    G --> H[Resume Execution]
    C -- No --> I[Continue]
    I --> H

(如果你更喜欢简洁的文本图示,请见下文。)

Function Starts → Execute Code → Await Durable Task?
    ↓                                    ↓
Continue                         Checkpoint State
    ↓                                    ↓
Complete/Next Step              Suspend Function

                                  Wait for Event/Timer

                                   Restore State

                                  Resume Execution

Source:

实际案例:文档审批工作流

下面是一个实用的文档审批系统,它:

  • 等待多个审阅者。
  • 发送提醒。
  • 如无人响应则升级处理。

Step Functions 中,这将是 15+ 个状态并伴随复杂的选择逻辑。使用 Durable Functions 则只需要几行代码。

import { DurableOrchestration } from '@aws-lambda/durable-functions';

export const documentApprovalWorkflow = new DurableOrchestration(
  async (context) => {
    const { documentId, reviewers } = context.input;

    // 1️⃣ 向所有审阅者发送通知
    await context.callActivity('sendReviewNotifications', {
      documentId,
      reviewers,
    });

    // 2️⃣ 等待审批并设置超时(7 天)
    const approvalTask = context.waitForEvent('approval', 7 * 24 * 60 * 60);
    const reminderTask = context.createTimer(3 * 24 * 60 * 60); // 3 天

    const winner = await Promise.race([approvalTask, reminderTask]);

    if (winner === 'reminder') {
      // 发送提醒并再次等待
      await context.callActivity('sendReminderEmails', { reviewers });
      const secondApproval = await context.waitForEvent('approval', 4 * 24 * 60 * 60);

      if (!secondApproval) {
        // 升级至经理
        await context.callActivity('escalateToManager', { documentId });
        await context.waitForEvent('managerApproval', 2 * 24 * 60 * 60);
      }
    }

    // 3️⃣ 处理审批结果
    const result = await context.callActivity('processApproval', {
      documentId,
      approvedAt: new Date().toISOString(),
    });

    return result;
  }
);

// 外部系统触发审批
export const submitApproval = async (workflowId: string, decision: string) => {
  await durableClient.raiseEvent(workflowId, 'approval', { decision });
};

关键要点: 代码读起来就像你向同事解释的脚本——没有 JSON,没有 $.decision == 'approved' 之类的条件,只有纯粹的编程逻辑。

Source:

多步骤应用:最佳场景

Durable Functions 在拥有 多个离散步骤、每个步骤可能耗时不同的情况下表现出色。以下模式非常适用。

1️⃣ 数据管道模式

您接收到文件上传后,经过多个转换处理,等待质量检查,然后发布结果。每一步可能根据文件大小耗时几秒到数小时不等。

Data Pipeline with Durable Functions

2️⃣ 人在环路模式

这正是 Durable Functions 绝对超越 Step Functions 的地方。任何需要等待人工决策的场景——批准、内容审核、手动数据录入——Durable Functions 都能让您:

  • 暂停执行而不产生费用。
  • 自动发送提醒或升级通知。
  • 在人工操作后从中断处继续执行。

3️⃣ 定时批处理模式

在一天中分块处理数据,汇总结果并生成报告。传统的 cron 任务无法在运行之间保持状态,而 Durable Functions 可以。

export const dailyReportWorkflow = new DurableOrchestration(
  async (context) => {
    const results = [];

    // Process batches every 6 hours
    for (let i = 0; i < 4; i++) {
      const batchResult = await context.callActivity('processBatch', {
        batchNumber: i,
        timestamp: new Date()
      });

      results.push(batchResult);

      // Wait 6 hours before next batch
      if (i < 3) {
        await context.createTimer(6 * 60 * 60);
      }
    }

    // Generate final report with all batches
    return await context.callActivity('generateReport', { results });
  }
);

Lambda Durable Functions vs. Step Functions: 诚实对比

FactorLambda Durable FunctionsStep Functions (Standard)
Max Duration365 天365 天
Waiting Cost$0(状态已持久化,函数挂起)前 4,000 次转换/月份后免费
Execution CostLambda 定价(每 100 万次请求 $0.20)每 100 万次状态转换 $25
State Machine代码化(TypeScript/Python)JSON ASL(Amazon 状态语言)
Versioning内置于代码部署中手动版本管理
Testing标准单元测试,本地调试需要 Step Functions Local 或 AWS
Visual Editor无(仅代码)Workflow Studio(拖拽式)
Error Handlingtry‑catch 块JSON 中的重试策略

成本细目示例

场景: 包含 8 步的审批工作流,平均等待 48 h 的人工响应,每月处理 50 000 份文档。

Step Functions 成本

  • 50 000 工作流 × 8 次状态转换 = 400 000 次转换
  • (400 000 – 4 000 免费额度) × $0.000025 = $9.90 / 月

Durable Functions 成本

  • 50 000 工作流 × 3 次 Lambda 调用(启动、恢复、完成) = 150 000 次请求
  • 150 000 × $0.0000002 = $0.03 / 月

节省: 对于等待时间较长的工作流,节省 99.7 %

何时 使用 Durable Functions

Durable Functions 很强大,但在以下情况下 Step Functions 仍然更胜一筹:

  • 需要可视化工作流编辑器 – 非技术利益相关者更喜欢 Step Functions 的 Workflow Studio。
  • 大量并行处理 – Step Functions 中的 Map 状态能够优雅地处理 10 000+ 并行分支。
  • AWS 服务集成 – Step Functions 提供 220+ 直接集成;Durable Functions 需要自定义代码。
  • 合规性要求 – 使用 Step Functions 的执行历史可以更轻松地生成可视化审计轨迹。

入门指南:您的第一个 Durable Function

使用 AWS SAM 模板

sam init --runtime nodejs20.x --app-template durable-function
cd my-durable-app
sam build && sam deploy --guided

或使用 CDK 部署

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as durable from '@aws-cdk/aws-lambda-durable-functions';

export class DurableStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string) {
    super(scope, id);

    const workflow = new durable.DurableFunction(this, 'MyWorkflow', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('functions/workflow'),
      timeout: cdk.Duration.minutes(15),
      maxDuration: cdk.Duration.days(365)
    });
  }
}

我通过艰难方式学到的最佳实践

  1. 使您的活动具备幂等性。 AWS 可能在失败后重试活动;请将其设计为能够优雅地处理重复调用。
  2. 不要在工作流状态中存储大数据。 状态限制为 256 KB——对于大负载请使用 S3,并传递引用。
  3. 使用关联 ID。 当外部系统向您的工作流发送信号时,给它们一个有意义的执行 ID(例如 order-{orderId}),而不是随机 UUID。
  4. 设置合理的超时时间。 工作流可以运行一年,但单个活动的超时时间应更短(秒到分钟)。
  5. 使用 CloudWatch 进行监控。 为卡住的工作流、失败的活动和异常的等待时间设置警报。

Durable Function Architecture Pattern

The Bottom Line

Lambda Durable Functions 代表了无服务器编排的重大演进。它们为您提供:

  • 简洁性 – 将工作流写成代码。
  • 成本节约 – 等待期间不产生费用。
  • 强大功能 – 工作流可运行最长一年。

如果您正在构建新的长时间运行的工作流——尤其是包含人工参与步骤或需要长时间等待的工作流——请从 Durable Functions 开始。您将编写更少的代码,支付更少的费用,并且可以安心入睡,因为您的工作流运行在经过实战检验的 AWS 基础设施上。

对于已有的 Step Functions… 如果您的工作流大部分时间都在等待,请考虑迁移。对于需要快速响应、拥有大量分支逻辑和 AWS 服务集成的工作流,Step Functions 仍可能是最佳选择。

无服务器的世界变得更加有趣。是时候构建可以运行一年的东西了。 🚀

有哪些工作流可以从 Durable Functions 中受益?在下方留言,让我们一起讨论!

Back to Blog

相关文章

阅读更多 »