

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

# AWS Flow Framework 基本概念：分布式执行
<a name="awsflow-basics-distributed-execution"></a>

*工作流实例*本质上是一个虚拟执行线程，可以跨越多台远程计算机上运行的活动和协调逻辑。Amazon SWF 以及作为操作系统的 AWS Flow Framework 功能，通过以下方式管理虚拟 CPU 上的工作流程实例：
+ 保留每个实例的执行状态。
+ 在实例之间切换。
+ 从切换位置恢复执行实例。

## 重播工作流程
<a name="replaying-workflows"></a>

由于活动可能长时间运行，最好不要在完成之前直接阻止工作流程。取而代之的是，使用*重播*机制来 AWS Flow Framework 管理工作流程的执行，该机制依靠由 Amazon SWF 维护的工作流程历史记录来分集执行工作流程。

每个阶段以某种方式重播工作流程逻辑，以便*仅执行一次每个活动*，并确保在其 [Promise](awsflow-basics-data-exchange-activities-workflows.md) 对象准备就绪后才执行活动和异步方法。

在启动工作流程执行时，工作流程启动程序启动第一个重播阶段。该框架调用工作流程的入口点方法，并且：

1. 执行所有不依赖于活动完成的工作流程任务，包括调用所有活动客户端方法。

1. 为 Amazon SWF 提供一个安排执行的活动任务列表。对于第一个阶段，该列表仅包含不依赖于 Promise 并且可立即执行的活动。

1. 通知 Amazon SWF 该阶段已完成。

Amazon SWF 会在工作流历史记录中存储活动任务，并通过将其放在活动任务列表中来安排执行。活动工作线程轮询任务列表并执行这些任务。

活动工作线程完成任务后，会将结果返回给 Amazon SWF，Amazon SWF 在工作流执行历史记录中记录该结果，并将其放在工作流任务列表中，以便为工作流工作线程安排新的工作流任务。工作流程工作线程轮询任务列表，并在收到该任务时运行下一个重播阶段，如下所示：

1. 该框架再次运行工作流程的入口点方法，并且：
   + 执行所有不依赖于活动完成的工作流程任务，包括调用所有活动客户端方法。不过，该框架检查执行历史记录，并且不会计划重复的活动任务。
   + 检查历史记录以查看哪些活动任务已完成，并执行依赖于这些活动的任何异步工作流程方法。

1. 在所有可执行的工作流任务都已完成后，该框架会向 Amazon SWF 报告：
   + 它会向 Amazon SWF 提供一份清单，列出自上一阶段以来输入 `Promise<T>` 对象已准备就绪并可安排执行的所有活动。
   + 如果该阶段没有生成任何额外的活动任务，但仍有未完成的活动，则框架会通知 Amazon SWF 该阶段已完成。然后，它等待另一个活动完成，从而启动下一个重播阶段。
   + 如果该阶段没有生成任何额外的活动任务，且所有活动都已完成，则框架会通知 Amazon SWF 工作流执行已完成。

有关重播行为的示例，请参阅[AWS Flow Framework 适用于 Java 重播行为](programming-replay.md)。

## 重播和异步工作流程方法
<a name="awsflow-basics-distributed-execution-async"></a>

异步工作流程方法的使用方式通常与活动非常相似，因为方法推迟执行，直到所有输入 `Promise<T>` 对象准备就绪。不过，重播机制处理异步方法的方式与活动不同。
+ 重播不保证异步方法仅执行一次。它推迟异步方法执行，直到其输入 Promise 对象准备就绪，但它为所有后续阶段执行该方法。
+ 在异步方法完成时，它不会启动新的阶段。

在[AWS Flow Framework 适用于 Java 重播行为](programming-replay.md)中提供了重播异步工作流程的示例。

## 重播和工作流程实现
<a name="awsflow-basics-distributed-execution-impl"></a>

在很大程度上，您不需要关注重播机制的细节。它基本上是在后台执行的操作。不过，重播对您的工作流程实现有两个重大影响。
+ 不要使用工作流程方法执行长时间运行的任务，因为重播将重复执行多次该任务。甚至异步工作流程方法通常也会运行多次。应使用活动执行长时间运行的任务；重播仅执行一次活动。
+ 您的工作流程逻辑必须是完全确定性的；每个阶段必须采用相同的控制流程路径。例如，控制流程路径不应依赖于当前时间。有关重播和确定性要求的详细说明，请参阅[不确定性](details.md#details.non)。