

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 对 Step Functions 中的问题进行故障排除
<a name="troubleshooting"></a>

如果您在使用 Step Functions 时遇到问题，请参阅以下故障排除资源。

以下主题为您可能遇到的与 Step Functions 状态机、服务集成、活动和工作流程相关的错误和问题提供故障排除建议。如果您发现某个问题未在此处列出，可以使用此页上的 **Feedback** 按钮来报告。

有关更多故障排除建议和常见支持问题的答案，请访问[AWS 知识中心](https://aws.amazon.com/premiumsupport/knowledge-center/#AWS_Lambda)。

**Topics**
+ [一般性问题](#troubleshooting-general)
+ [服务集成](#troubleshooting-service-integrations)
+ [活动](#troubleshooting-activities)
+ [快速工作流](#troubleshooting-express-workflows)
+ [分布式地图](#troubleshooting-distributed-maps)

## 一般故障排除
<a name="troubleshooting-general"></a>

### 我无法创建状态机。
<a name="troubleshooting-general-unable-to-create"></a>

与状态机关联的 IAM 角色可能没有[足够的权限](auth-and-access-control-sfn.md#auth-and-access-control-sfn.title)。检查 IAM 角色的权限，包括 AWS 服务集成任务和 CloudWatch 日志记录的权限。 X-Ray`.sync` 任务状态需要额外的权限。

### 我无法使用 JsonPath 来引用上一个任务的输出。
<a name="troubleshooting-general-unable-to-use-json"></a>

对于 a JsonPath，JSON 密钥必须以结尾`.$`。这意味着 a JsonPath 只能在键值对中使用。如果你想使用 JsonPath 其他地方，比如数组，你可以使用[内部函数](intrinsic-functions.md)。例如，可以使用类似以下代码的内容：

**任务 A 的输出：**

```
{
    "sample": "test"
}
```

**任务 B：**

```
{
    "JsonPathSample.$": "$.sample"
}
```

### 状态转换出现延迟。
<a name="troubleshooting-general-state-transition-delay"></a>

对于标准工作流，状态转换的数量是有限制的。当超过状态转换限制时，Step Functions 会延迟状态转换，直到配额存储桶填满。可以通过查看 “ CloudWatch 指标” 页面[执行指标](procedure-cw-metrics.md#cloudwatch-step-functions-execution-metrics)部分中的`ExecutionThrottled`指标来监控状态转换限制情况。

### 启动新的标准工作流执行时，会执行失败并出现 `ExecutionLimitExceeded` 错误。
<a name="troubleshooting-general-unable-to-start-standard-workflows"></a>

Step Functions 每次的开放执行上限为 100 万个 AWS 账户 。 AWS 区域如果超过此限制，Step Function 会抛出 `ExecutionLimitExceeded` 错误。此限制不适用于快速工作流程。可以使用 `OpenExecutionCount` 来跟踪何时接近 `OpenExecutionLimit`，并创建警报来在该事件中主动通知您。`OpenExecutionCount` 是已开启工作流程的大致数量。有关更多信息，请参阅 [执行指标](procedure-cw-metrics.md#cloudwatch-step-functions-execution-metrics)。

### 一个处于并行状态的分支出现故障，导致整个执行失败。
<a name="troubleshooting-general-branch-failure-causes-execution-failure"></a>

这是一个预期行为。为避免在使用并行状态时遇到故障，请将 Step Functions 配置为[捕获每个分支抛出的错误](concepts-error-handling.md#error-handling-fallback-states.title)。

## 服务集成故障排除
<a name="troubleshooting-service-integrations"></a>

### 在下游服务中，我的作业已经完成，但在 Functions 中，任务状态仍为“进行中”或延迟完成。
<a name="troubleshooting-service-integrations-task-delay"></a>

对于`.sync`服务集成模式，Step Functions 使用 EventBridge 规则、下游 API 或两者的组合来检测下游作业状态。对于某些服务，Step Functions 不会创建要监控的 EventBridge 规则。例如，对于 AWS Glue 服务集成，Step Functions 不是使用 EventBridge 规则，而是`glue:GetJobRun`调用。由于 API 调用的频率，下游任务完成时间与 Step Functions 任务完成时间存在差异。Step Functions 需要 IAM 权限才能管理 EventBridge 规则和调用下游服务。有关执行角色权限不足如何影响任务完成的详细信息，请参阅[使用 .sync 的任务的额外权限](service-integration-iam-templates.md#connect-iam-sync-async)。

### 我想从嵌套状态机执行中返回 JSON 输出。
<a name="troubleshooting-service-integrations-json-from-nested"></a>

Step Functions 有两个同步服务集成：`startExecution.sync` 和 `startExecution.sync:2`。两者都将等待嵌套状态机完成，但它们返回不同的 `Output` 格式。您可以使用 `startExecution.sync:2` 在 `Output` 下返回 JSON 输出。

### 我无法从另一个账户调用 Lambda 函数。
<a name="troubleshooting-service-integrations-invoke-lambda-from-account"></a>

**通过跨账户支持访问 Lambda 函数**  
如果您的地区支持[跨账户访问](concepts-access-cross-acct-resources.md) AWS 资源，请使用以下方法从其他账户调用 Lambda 函数。

要在工作流中调用跨账户资源，请执行以下操作：

1. 在包含资源的目标账户中创建 IAM 角色。此角色向包含状态机的源账户授予访问目标账户资源的权限。

1. 在 `Task` 状态的定义中，指定在调用跨账户资源之前由状态机担任的目标 IAM 角色。

1. 修改目标 IAM 角色中的信任策略来允许源账户临时担任此角色。信任策略必须包含源账户中定义的状态机的 Amazon 资源名称（ARN）。此外，还要在目标 IAM 角色中定义调用 AWS 资源的相应权限。

1. 更新源账户的执行角色，使其包含担任目标 IAM 角色所需的权限。

有关示例，请参阅教程中的[在 Step Functi AWS ons 中访问跨账户资源](tutorial-access-cross-acct-resources.md)。

**注意**  
您可以配置状态机承担一个 IAM 角色，以便从多个 AWS 账户访问资源。但是，状态机在给定时间只能承担一个 IAM 角色。

有关指定跨账户资源的 `Task` 状态定义示例，请参阅 [Task 状态的“凭证”字段示例](state-task.md#task-state-example-credentials)。

**在没有跨账户支持的情况下访问 Lambda 函数**  
如果您所在的地区无法跨账户访问 AWS 资源，请使用以下方法从其他账户调用 Lambda 函数。

在 `Task` 状态的 `Resource` 字段中，使用 `arn:aws:states:::lambda:invoke` 并传递参数中的 `FunctionArn`。与状态机关联的 IAM 角色必须拥有调用跨账户 Lambda 函数的正确权限：`lambda:invokeFunction`。

```
{  
   "StartAt":"CallLambda",
   "States":{  
      "CallLambda":{  
         "Type":"Task",
         "Resource":"arn:aws:states:::lambda:invoke",
         "Parameters":{  
            "FunctionName":"arn:aws:lambda:{{region}}:{{account-id}}:function:my-function"
         },
         "End":true
      }
   }
}
```

### 我看不到从 `.wait ForTaskToken` 状态传递的任务令牌。
<a name="troubleshooting-service-integrations-unable-to-see-task-tokens"></a>

 您必须在 `Task` 状态的 `Parameters` 字段中传递任务令牌。例如，您可以使用与以下代码类似的内容。

```
{  
   "StartAt":"taskToken",
   "States":{  
      "taskToken":{  
         "Type":"Task",
         "Resource":"arn:aws:states:::lambda:invoke.waitForTaskToken",
         "Parameters":{  
            "FunctionName":"get-model-review-decision",
            "Payload":{  
               "token.$":"$$.Task.Token"
            },
         },
         "End":true
      }
   }
}
```

**注意**  
您可以尝试在任何 API 操作中使用 `.waitForTaskToken`。不过，有些 API 没有合适的参数。

## 活动故障排除
<a name="troubleshooting-activities"></a>

### 我的状态机执行卡在活动状态。
<a name="troubleshooting-activities-stuck-state-machine"></a>

只有在您使用 [GetActivityTask](https://docs.aws.amazon.com/step-functions/latest/apireference/API_GetActivityTask.html)API 操作轮询任务令牌后，活动任务状态才会启动。最佳实操是添加任务级超时，用于避免执行卡住。有关更多信息，请参阅 [使用超时来避免 Step Functions 工作流程执行卡顿](sfn-best-practices.md#sfn-stuck-execution)。

如果您的状态机在[ActivityScheduled](https://docs.aws.amazon.com/step-functions/latest/apireference/API_ActivityScheduledEventDetails.html)事件中停滞不前，则表明您的活动工作人员队列存在问题或规模不足。您应该监控该[`ActivityScheduleTime`](procedure-cw-metrics.md#cloudwatch-step-functions-activity-metrics) CloudWatch 指标，并在该时间延长时设置警报。不过，要想超时处理任何卡住的状态机执行（其中 `Activity` 状态没有转换到 `ActivityStarted` 状态），可在状态机级别定义超时。为此，请在状态机定义的开头指定一个 `TimeoutSeconds` 字段，该字段位于 `States` 字段之外。

### 我的活动工作线程在等待任务令牌时超时。
<a name="troubleshooting-activity-worker-times-out"></a>

工作人员使用 [GetActivityTask](https://docs.aws.amazon.com/step-functions/latest/apireference/API_GetActivityTask.html)API 操作来检索具有指定活动 ARN 的任务，该任务计划由正在运行的状态机执行。 `GetActivityTask`开始长时间的轮询，因此该服务保持 HTTP 连接处于打开状态，并在任务可用时立即做出响应。服务在响应之前保留请求的最长时间为 60 秒。如果在 60 秒内没有任务可用，轮询将返回一个带空字符串的 `taskToken`。要避免这种超时，请在 AWS SDK 或用于进行 API 调用的客户端中将客户端套接字配置为至[少 65 秒的超](https://docs.aws.amazon.com/step-functions/latest/apireference/API_GetActivityTask.html)时时间。

## 快速工作流程故障排除
<a name="troubleshooting-express-workflows"></a>

### 我的应用程序在收到来自某人的回复之前就超时了 `[StartSyncExecution](https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartSyncExecution.html)`API 调用。
<a name="troubleshooting-express-workflows-timeouts"></a>

在用于进行 API 调用的 AWS SDK 或客户端中配置客户端套接字超时。要接收响应，超时值必须高于快速工作流执行的持续时间。

### 我无法查看执行历史记录，无法解决快速工作流故障。
<a name="troubleshooting-express-workflows-no-execution-history"></a>

快速工作流不会在 AWS Step Functions中记录执行历史。相反，您必须开启 CloudWatch 日志记录。开启日志记录后，你可以使用 L CloudWatch ogs Insights 查询来查看 Express Workflow 的执行情况。如果在**执行**选项卡中选择**启用**按钮，还可以在 Step Functions 控制台上查看快速工作流的执行历史记录。有关更多信息，请参阅 [在 Step Functions 控制台中查看执行详细信息](concepts-view-execution-details.md)。

根据持续时间列出执行情况：

```
fields ispresent(execution_arn) as exec_arn
| filter exec_arn 
| filter type in ["ExecutionStarted", "ExecutionSucceeded", "ExecutionFailed", "ExecutionAborted", "ExecutionTimedOut"]
| stats latest(type) as status, 
  tomillis(earliest(event_timestamp)) as UTC_starttime, 
  tomillis(latest(event_timestamp)) as UTC_endtime, 
  latest(event_timestamp) - earliest(event_timestamp) as duration_in_ms  by execution_arn
| sort duration_in_ms desc
```

列出失败和取消的执行：

```
fields ispresent(execution_arn) as isRes | filter type in ["ExecutionFailed", "ExecutionAborted", "ExecutionTimedOut"]
```

## 分布式地图疑难解答
<a name="troubleshooting-distributed-maps"></a>

### 我的地图运行卡住了。
<a name="troubleshooting-distributed-maps-stuck-map-run"></a>

[打开地图的最大运行次数](https://docs.aws.amazon.com/step-functions/latest/dg/service-quotas.html#service-limits-accounts)有服务配额。此配额用完后，其他地图将等待其他地图运行完成后有更多配额可用。积压的地图在`MapRunStarted`事件发生后等待，然后再读取他们的输入，因此你会看到地图运行的待处理物品数量保持在 0。一旦积压的地图能够获得配额，它将开始读取其输入。然后，您将看到待处理的物品数量增加，并且地图将在其生命周期的剩余时间内正常运行。随着配额可用，在积压的地图中分配配额的方式没有特定的顺序。

使用嵌套映射运行时存在死锁的风险。在这种情况下，您有一个包含 “父” 地图运行的父工作流程执行，这反过来又会启动包含 “子” 地图运行的子工作流程执行，这反过来又会启动孙子工作流程执行。如果子工作流程执行开始其子*地图运行时没有剩余的最大打开地图运行次数*配额，则该子地图运行将被积压。如果父地图运行消耗了全部配额，并且所有子地图运行都被积压了，那么两个组都无法取得进展，并且在配额再次可用之前，他们将保持僵局。地图运行将在父执行终止（例如超时、由于未捕获的错误而失败或由于 API 调用而失败）时中止并使其配额再次可用。`StopExecution`

考虑在工作流程设计中使用嵌套地图运行时，请估计您的预期开放地图运行次数是否可能超过*最大开放地图运行次数*配额，从而使您面临延迟或死锁的风险。如果是这样，你可以考虑其他设计。例如，与其使用父映射运行来迭代 Amazon S3 对象列表，使用子地图运行来读取其内容，不如使用地图运行中的[`LOAD_AND_FLATTEN`转换](https://docs.aws.amazon.com/step-functions/latest/dg/input-output-itemreader.html#itemreader-flatten)在一次地图运行中执行这两个操作。`ReaderConfig`另一种常见的模式是包括预处理步骤，例如 Lambda 函数，该函数会迭代您的嵌套数据并生成可用作地图运行输入的文件。

您可以使用中的`ApproximateOpenMapRunCount`、`OpenMapRunLimit`和`ApproximateMapRunBacklogSize`指标[监控自己](https://docs.aws.amazon.com/step-functions/latest/dg/procedure-cw-metrics.html#resource-count-metrics-map-run)*对最大开放地图运行次数*配额的使用情况 CloudWatch。