Fault-oblivious [译注: 该词可能来源于该论文 Failure-Oblivious Computing,统一翻译成故障忽略]故障忽略的, 有状态的 Workflow 代码是 Temporal 的核心抽象。但是,由于对工作流执行需要保证确定性,不允许他们直接调用任何外部 API。相反,他们策划执行 Activities 。在其最简单的形式中, Temporal Activities 是所支持的语言之一中的函数或对象方法。在发生故障时, Temporal 不会恢复 Activities 状态。因此,允许 Activities 功能不受限制地包含任何代码。

Activities 通过 Task Queue 异步调用。 Task Queue 本质上是用于存储 Activities 任务的队列,供 Worker 接收任务。 Worker 通过调用 Activities 执行函数来处理 Activities 。当番薯返回时, Worker 将结果报告给 Temporal 服务,后者又通知 Workflow 有关完成情况。通过从不同的进程[程序]完成 Activities ,完全异步执行 Activities 是可行的。

超时

Temporal 不对 Activities 持续时间施加任何系统限制。它是由应用程序来控制超时时间。以下是可配置的 Activities 超时选项:

  • ScheduleToStart:从调用 Activities 执行到 Worker 开始 Activities 执行的最长时间。此超时出现的通常原因是当所有员工都处于下降或无法跟上请求率时。我们建议将此超时设置为最大值,这样 Workflow 可以等待 Worker 就绪并执行 Activities 。无论重试策略如何,此超时不会触发任何重试。除非您知道自己在做什么,否则不要使用此超时。
  • StartToClose:单个 Activities 执行尝试的最长时间。
  • ScheduleToClose:整体 Activities 执行的最长时间,包括从”计划启动ScheduleToStart“和”重试”中执行的时间。
  • Heartbeat:心跳请求之间的最长时间。当 Activities 调用心跳 API 时,除非指定心跳超时,否则调用不会发送到服务。如果指定了心跳超时,则 Activities 必须在此超时内调用心跳 API。请参阅Long Running Activities

ScheduleToCloseStartToClose中需要制定其中一个.

重试

由于 Temporal 无法恢复 Activities 状态,并且它们可以与任何外部系统通信,故障是必须考虑也一定会发生的。因此, Temporal 支持自动 Activities 重试。调用的任何 Activities 都可以具有相关的重试策略。以下是重试策略参数:

  • InitialInterval是第一次重试前的延迟。
  • BackoffCoefficient.重试策略是指数级的。系数指定重试间隔的生长速度。值为 1 表示重试间隔始终等于InitialInterval
  • MaximumInterval指定重试之间的最大间隔。对系数大于 1 有用。
  • MaximumAttempts指定在出现故障时尝试执行 Activities 的次数。如果超出此限制,则错误将返回到调用 Activities 的 Workflow 。
  • NonRetryableErrorReasons允许您指定不应重试的错误。例如,在某些情况下重试无效参数错误是没有意义的。

有些情况下,不只是需要重试单个 Activities ,而是应在单个 Activites 失败时重试 Workflow 的整个部分。例如,一个用于媒体编码的 Workflow ,将文件下载到主机,处理它,然后将结果上传回存储系统。在此 Workflow 中,如果托管该 Worker 的主机死亡,则应在不同的主机上重试所有三个 Activities[译注: 即下载文件, 处理,回传这三个 Activites] 。此类重试应由 Workflow 代码处理,因为它们仅适用于特定的使用案例。

Long Running Activities

对于 Long Running Activities ,我们建议您指定一个相对较短的心跳超时和持续的心跳。这样,即使长时间运行 Activities ,也能及时处理 Worker 故障。指定心跳超时的 Activities 预计会在执行的时候中定期 调用心跳强求。
心跳请求可以包括应用程序特定的有效载荷[比如当前状态]。这有助于保存 Activities 执行进度。如果 Activities 因心跳错过而超时,执行该 Activities 的下一次重试可以访问该进度并从该点继续执行。

长期运行 Activities 的使用场景包括领导选举。 Temporal 超时拥有更粗的粒度[比如几秒]。因此,它不是实时应用程序的解决方案。但是,如果在几秒钟内对过程失败做出反应是可以的[接收延迟],那么 Temporal 心跳 Activities 是一个很好的选择。

这种领导人选举的一个常见用例是监测。 Activities 执行内部循环,定期对某些 API 进行投票并检查某些情况。它也在每一个迭代中发送心跳。如果条件得到满足, Activities 将完成,从而允许其 Workflow 处理它。如果 Activities 工作者死亡,则 Activities 时间超过心跳间隔后,将在其他 Worker 上进行重试。相同的模式适用于亚马逊 S3 存储桶中的新文件的轮询或 REST 或其他同步 API 中的响应。

取消

Workflow 可以请求 Activities 取消。目前, Activities 得知被取消的唯一方法是通过心脏跳动。心跳请求失败,出现特殊错误,指示 Activities 已取消。然后,由 Activities 实施者执行所有必要的清理并报告已完成取消。它由 Workflow 实现来决定是否要等待 Activities 取消确认。

Activities 心跳失败的另一个常见情况是,调用它的 Workflow 处于已完成状态。在这种情况下, Activities 也需要进行清理。

通过 Task Queue 进行 Activities 任务路由

Activities 通过 Task Queue 发送给 Worker 。 Task Queue 是 Worker 监听的队列。 Task Queue 具有高度动态性和轻量级。它们不需要明确注册。每个 Worker 流程可以有一个 Task Queue 。通过单个 Task Queue 调用多个 Activities 类型是正常的。在某些情况下(如主机路由)在多个 Task Queue 中调用相同的 Activities 类型是正常的。

以下是在单个 Workflow 中使用多个 Activities Task Queue 的一些用例:

  • 流量控制。仅在有承载能力的情况下,Worker 才会请求 Activities 任务。因此, Worker 永远不会因为请求峰值而超负荷工作。如果 Activities 执行请求生成的速度比 Worker 处理它们的速度快,则它们会积压在 Task Queue 中。
  • 速率限制。每个 Activities Worker 可以指定在 Task Queue 中处理 Activities 的最大速率。即使有足够的承载能力,也不会超过此限制。此外,还支持限制全系统 Task Queue 速率。此限制适用于给定 Task Queue 的所有 Worker 。它经常用于限制 Activities 调用的下游服务的负载。
  • 独立部署一组 Activities 。考虑托管 Activities 并可独立于其他 Activities 和 Workflow 部署的服务。要将 Activities 任务发送到此服务,需要单独的 Task Queue 。
  • 具有不同能力的 Worker 。例如,GPU 处理与非 GPU 处理的 Worker 。在这种情况下,有两个单独的 Task Queue 允许 Workflow 选择向 Activities 发送执行请求的哪个队列。
  • 将 Activities 路由到特定主机。例如,在媒体编码的情况下,转换和上传 Activities 必须在下载的同一主机上运行。
  • 将 Activities 路由到特定进程。例如,某些 Activities 加载大数据集并在此程序中缓存。依赖此数据集的 Activities 应路由到相同的程序。
  • 多个优先级。每个优先级一个 Task Queue ,每个优先级有一个 Worker 池。
  • 版本。 Activities 的新的向后不兼容的实现就可以会使用不同的 Task Queue 。

异步完成 Activities

默认情况下, Activities 是一种函数或方法,具体取决于客户端库语言。函数 Return 的时候, Activities 就会完成。但在某些情况下, Activities 实现是异步的。例如,它通过消息队列转发到外部系统。完成的消息是通过其他队列传递。

为了支持此类使用案例,Temporal 允许在 Activities 的函数 Return 后 Activities 并不标记完成。在这种情况下,应使用一个分离的单独的 API 来完成 Activities 。此 API 可以从任何过程中(即使是以不同的编程语言)调用。[这部分对新手理解困难, 特翻了注释评论到旁边]

本地 Activities

有些 Activities 寿命很短,不需要语义、流量控制、速率限制和路由功能。对于这些 Temporal 支持所谓的本地 Activities 功能。本地 Activities 与调用它们的 Workflow 在同一个 Worker 流程中执行。考虑以下几点后来使用本地 Activities 履行职能:

  • 不超过几秒钟的调用
  • 不需要全局速率限制
  • 不需要路由到特定的 Worker 或 Worker 池
  • 可以与调用它们的 Workflow 以相同的二进制实现

本地 Activities 的主要好处是,它们在利用 Temporal 服务资源方面效率要高得多,与通常的 Activities 调用相比,其延迟间接费用要低得多。[主要原因是不经过网络调用,类似于从 RPC 编程了 Function Call.]