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

如何在状态机配置内让同状态机后续调用等待前序执行完成

基于Step Functions状态机配置实现串行执行(无需队列)

可以通过DynamoDB分布式锁+状态机内置重试/等待逻辑实现,完全在状态机配置内完成,无需额外队列服务。核心是让每个状态机执行实例启动时先尝试获取全局锁,只有拿到锁的实例才能执行业务逻辑,未拿到的则循环等待直到锁被释放。

具体实现步骤

1. 准备DynamoDB锁表

创建一个极简的DynamoDB表(推荐表名StateMachineGlobalLock):

  • 主键设为LockKey(字符串类型),固定使用SingleExecutionLock作为键值
  • 额外添加OwnerExecutionId(字符串)和ExpirationTime(数字,存储Unix时间戳)两个字段,前者记录当前持锁的执行ID,后者用于处理执行意外失败的锁过期场景

2. 状态机核心逻辑(ASL配置)

状态机分为四个关键阶段:尝试获取锁、等待重试、执行业务、释放锁,以下是完整示例配置:

{
  "Comment": "串行执行状态机,基于DynamoDB锁避免并行",
  "StartAt": "AcquireGlobalLock",
  "States": {
    "AcquireGlobalLock": {
      "Type": "Task",
      "Resource": "arn:aws:states:::dynamodb:putItem",
      "Parameters": {
        "TableName": "StateMachineGlobalLock",
        "Item": {
          "LockKey": {"S": "SingleExecutionLock"},
          "OwnerExecutionId": {"S": "$$.Execution.Id"},
          "ExpirationTime": {"N": "${Math.floor(Date.now()/1000) + 3600}"}
        },
        "ConditionExpression": "attribute_not_exists(OwnerExecutionId) OR ExpirationTime < :currentTimestamp",
        "ExpressionAttributeValues": {
          ":currentTimestamp": {"N": "${Math.floor(Date.now()/1000)}"}
        }
      },
      "Catch": [
        {
          "ErrorEquals": ["ConditionalCheckFailedException"],
          "Next": "WaitBeforeRetry"
        }
      ],
      "Next": "ProcessS3Upload"
    },
    "WaitBeforeRetry": {
      "Type": "Wait",
      "Seconds": 15,
      "Next": "AcquireGlobalLock"
    },
    "ProcessS3Upload": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:YourS3FileProcessor",
      "Next": "ReleaseGlobalLock"
    },
    "ReleaseGlobalLock": {
      "Type": "Task",
      "Resource": "arn:aws:states:::dynamodb:updateItem",
      "Parameters": {
        "TableName": "StateMachineGlobalLock",
        "Key": {"LockKey": {"S": "SingleExecutionLock"}},
        "UpdateExpression": "REMOVE OwnerExecutionId, ExpirationTime",
        "ConditionExpression": "OwnerExecutionId = :currentExecutionId",
        "ExpressionAttributeValues": {
          ":currentExecutionId": {"S": "$$.Execution.Id"}
        }
      },
      "End": true
    }
  }
}

关键细节说明

  • 锁的原子性:通过DynamoDB的条件写入(ConditionExpression)保证同一时间只有一个执行实例能获取锁,彻底避免并行执行
  • 锁过期机制:ExpirationTime字段设置为当前时间+业务最大预估执行时长(示例中为1小时),如果持锁实例意外崩溃,锁会自动过期,后续执行可以正常获取
  • 重试策略:WaitBeforeRetry的等待时长可根据业务调整,平衡重试频率和资源消耗
  • 锁释放安全:释放锁时的条件表达式确保只有当前持锁的执行实例能释放锁,防止其他实例误操作

内容的提问来源于stack exchange,提问作者T K R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:50:54