如何为 Cadence 活动(本地和常规活动,带或不带重试)设置适当的超时值?

Lon*_*eng 5 cadence-workflow uber-cadence

所以有这么多的超时值:

对于当地活动

  • 计划关闭超时

对于无需重试的常规活动

  • 计划开始超时
  • 计划关闭超时
  • 开始到关闭超时
  • 心跳超时

然后retryOptions中有更多值:

  • 过期时间间隔
  • 初始间隔
  • 退避系数
  • 最大间隔
  • 最大尝试次数

retryOptions 可以应用于 localActivity 或常规活动。

我如何将它们一起使用,有何期望?

Lon*_*eng 7

长话短说

使用超时的最简单方法:

常规活动重试

  1. 使用 StartToClose 作为每次尝试的超时
  2. 将 ScheduleToStart 和 SchedueToClose 留空
  3. 如果 StartToClose 太大(如 10 分钟),则将 Heartbeat 超时设置为较小的值,如 10 秒。定期调用activity内部的heartbeat API。
  4. 使用 retryOptions.InitialInterval、retryOptions.BackoffCoefficient、retryOptions.MaximumInterval 来控制退避。
  5. 使用 retryOptions.ExperiationInterval 作为所有尝试的总体超时。
  6. 将 retryOptions.MaximumAttempts 留空。

无需重试的常规活动

  1. 使用 ScheduleToClose 实现整体超时
  2. 将 ScheduleToStart 和 StartToClose 留空
  3. 如果 ScheduleToClose 太大(例如 10 分钟),则将 Heartbeat 超时设置为较小的值,例如 10 秒。定期调用activity内部的heartbeat API。

LocalActivity 无需重试:使用 ScheduleToClose 实现整体超时

LocalActivity 重试

  1. 使用 ScheduleToClose 作为每次尝试的超时。
  2. 使用 retryOptions.InitialInterval、retryOptions.BackoffCoefficient、retryOptions.MaximumInterval 来控制退避。
  3. 使用 retryOptions.ExperiationInterval 作为所有尝试的总体超时。
  4. 将 retryOptions.MaximumAttempts 留空。

更多 TL;DR

因为活动应该是幂等的,所以所有活动都应该设置重试策略。默认情况下,Temporal 为任何活动设置了无限重试策略。在我看来,Cadence 应该做同样的事情。

iWF还为状态 API 设置默认的无限重试以匹配时间活动。

什么和为什么

无需重试的基础知识

无需重试,世界上的事情就更容易理解。因为Cadence就是从它开始的。

  • ScheduleToClose 超时是从工作流角度来看的总体端到端超时。

  • ScheduleToStart 超时是活动工作人员启动活动所需的时间。超过此超时,活动将向工作流返回 ScheduleToStart 超时错误/异常

  • StartToClose 超时是活动需要运行的时间。超过此值将使 StartToClose 返回到工作流程。

  • 要求和默认值:

    • 提供 ScheduleToClose 或同时提供 ScheduleToStart 和 StartToClose。
    • 如果只有 ScheduleToClose,则 ScheduleToStart 和 StartToClose 是默认的。
    • 如果仅提供 ScheduleToStart 和 StartToClose,则ScheduleToClose = ScheduleToStart + StartToClose.
    • 所有这些都受到工作流超时的限制。(例如,如果工作流超时为 1 小时,为 ScheduleToClose 设置 2 小时仍将获得 1 小时ScheduleToClose=Min(ScheduleToClose, workflowTimeout):)

那么他们为什么会这样呢?

您可能会注意到 ScheduleToClose 仅​​在以下情况下才有用 ScheduleToClose < ScheduleToStart + StartToClose。因为如果ScheduleToClose >= ScheduleToStart+StartToCloseScheduleToClose 超时已经由其他两者的组合强制执行,那么它就变得毫无意义。

因此 ScheduleToClose 小于两者之和的主要用例是人们希望限制活动的总体超时,但为 ScheduleToStart 或 startToClose 提供更多超时。这是极其罕见的用例

人们想要区分 ScheduleToStart 和 StartToClose 的主要用例是工作流可能需要对 ScheduleToStart 超时错误进行一些特殊处理。这也是非常罕见的用例

因此,您可以理解为什么在 TL;DR 中我建议仅使用ScheduleToClose而将其他两个留空。因为只有在极少数情况下您可能需要它。如果您想不出用例,那么您就不需要它。

LocalActivity 没有 ScheduleToStart/StartToClose,因为它直接在工作流工作线程内部启动,不涉及服务器调度。

心跳超时

心跳对于长时间跑步活动非常重要,可以防止其卡住。不仅错误会导致活动卡住,定期部署/主机重新启动/故障也可能导致它。因为没有心跳,Cadence 服务器无法知道该活动是否仍在进行。请参阅此处的更多详细信息解决 Cadence/SWF/StepFunctions 中卡住的计时器/活动的解决方案

RetryOptions 和重试活动

首先,这里的RetryOptions用于server side退避重试——这意味着重试由Cadence自动管理,无需与工作流程交互。由于重试是由 Cadence 管理的,因此必须在 Cadence 历史记录中对 Activity 进行特殊处理,直到 Activity 关闭后才能写入已启动的事件。这里有一些参考:为什么活动任务被调度但没有启动?

事实上,工作流可以client side自行重试。这意味着工作流将管理重试逻辑。您可以编写自己的重试函数,或者 SDK 中有一些辅助函数,例如Workflow.retryCadence-java-client 中的函数。客户端重试将立即显示所有启动事件,但重试单个活动时历史记录中会有许多事件。由于性能问题,不推荐使用。

那么选项的含义是什么:

  • 到期间隔:

    • 它取代 ScheduleToClose 超时,成为所有尝试的活动的实际总体超时。
    • 与其他三个超时选项一样,它也受到工作流超时的限制。ScheduleToClose = Min(ScheduleToClose, workflowTimeout)
    • 每次尝试的超时时间是 StartToClose,但 StartToClose 默认为 ScheduleToClose,如上面的说明。
    • ScheduleToClose 将扩展为 ExpirationInterval: ScheduleToClose = Max(ScheduleToClose, ExpirationInterval),这发生在 ScheduleToClose 复制到 ScheduleToClose 和 StartToClose 之前。
  • InitialInterval:第一次重试的时间间隔

  • BackoffCoefficient:自我解释

  • MaximumInterval:重试期间的最大间隔

  • MaximumAttempts:最大尝试次数。如果存在 ExpirationInterval,则当超过其中任何一个时,重试将停止。

  • 要求和默认值

  • MaximumAttempts 或 ExpirationInterval 是必需的。如果未提供,ExpirationInterval 将设置为workflowTimeout。

由于 ExpirationInterval 总是存在的,而且实际上它更有用。大多数时候,使用MaximumAttempts比较困难,因为它很容易与backoffCoefficient混淆(例如,当backoffCoefficient>1时,如果不小心,端到端超时可能会非常大)。所以我建议只使用 ExpirationInterval。除非你真的需要它。