iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0
Software Development

Temporal 開發指南:掌握 Workflow as Code 打造穩定可靠的分散式流程系列 第 11

Day11 - 不要讓流程無限等:Timeout Policy 的設計思維

  • 分享至 

  • xImage
  •  

在分散式流程中,網路延遲、第三方不穩與長任務不可避免,Timeout 與 Retry 的規則設定是推進及修復流程的一大重點。

本篇首先介紹 Timeout Policy,提供可落地的設定方法,避免單次執行無限等待、釋放被占用的執行緒,並為下一篇的 Retry Policy 奠定基礎。

1. Timeout 與 Retry 的本質介紹

  • Timeout:保護機制(防止卡死、釋放資源)。
  • Retry:回復機制(再試一次,直到完成)。
  • 兩者的互動:
    • Timeout 發生 → 任務被中斷 → Retry 規則生效再試一次。
    • 沒有 Timeout,執行就可能卡住。
    • 沒有 Retry,Timeout 就只會讓流程失敗。

2. Activity Timeout 的設計

2.1 Temporal 的 Activity Timeout 的類型

類型 作用 典型場景 設定建議
Start-to-Close 限制單次 Activity 執行時間 呼叫外部 API、單步 DB 操作 依 P95~P99 Latency ×2~3 倍
Schedule-to-Start 限制排隊等待時間 高峰期工作擁塞 高於平均排隊時間的 2~3 倍
Schedule-to-Close 等待+執行的整體上限 SLA 需要端到端保障 覆蓋整體最壞情況但避免過長
Heartbeat 長任務活性與進度回報 批次處理、檔案搬移、匯入 5–30 秒;與 checkpoint 一起用

2.2 Activity Timeout 的設定思維

  • 原則:

    • 以實測 P95/P99 為基礎估算,Start-to-Close 建議取 P99×2(留安全緩衝)。
    • 短任務用短 Timeout(幾秒到十數秒),避免卡死執行緒。
    • 長任務必備 Heartbeat(5–30 秒回報一次),縮短回復成本。
    • 能短就短:優先採「較短 Timeout + Heartbeat + checkpoint」,少用超長 Timeout。
  • 快速檢查:

    • Start-to-Close 是否覆蓋單次執行的合理上限?
    • Schedule-to-Start 是否涵蓋尖峰期排隊等待時間?
    • Schedule-to-Close 是否滿足端到端步驟上限(等待+執行)?
    • HeartbeatTimeout 是否至少涵蓋一個安全的進度回報窗口?
  • 常見錯誤:

    • Timeout 設太長 → 執行緒被佔用過久、吞吐下降。
    • Timeout 設太短 → 輕易引發重試風暴。
    • 缺少 Heartbeat → 長任務失敗只能整批重跑,回復代價高。
  • 程式碼範例

// 定義 Activity 的超時/重試/心跳等行為,建議在 Activity 層完成
ActivityOptions commonOptions = ActivityOptions.newBuilder()
    // 單次執行上限(Start-to-Close):避免單次呼叫卡住
    .setStartToCloseTimeout(Duration.ofSeconds(10))
    // 佇列等待上限(Schedule-to-Start):避免長時間排隊
    .setScheduleToStartTimeout(Duration.ofSeconds(5))
    // 端到端上限(Schedule-to-Close):等待+執行的整體上限(可視需要)
    .setScheduleToCloseTimeout(Duration.ofSeconds(20))
    // 長任務需心跳(Heartbeat),超時視為失敗並可由 checkpoint 繼續
    .setHeartbeatTimeout(Duration.ofSeconds(10))
    // 重試策略(詳見下一節 RetryOptions)
    .setRetryOptions(RetryOptions.newBuilder()
        .setMaximumAttempts(5)
        .setInitialInterval(Duration.ofSeconds(1))
        .setBackoffCoefficient(2.0)
        .setMaximumInterval(Duration.ofSeconds(20))
        .setDoNotRetry("InvalidInput", "InvalidState")
        .build())
    .build();

// 在 Workflow 內以 options 建立活動 stub,即可套用以上設定
MyActivities acts = Workflow.newActivityStub(MyActivities.class, commonOptions);

3. Workflow Timeout(大多數情境無須設定,用預設值即可)

3.1 Temporal 的 Workflow Timeout 的類型

類型 作用 典型場景 設定建議
WorkflowRunTimeout 單次 run 的上限(不跨 run) 長流程單次執行的最大容忍時間 依步驟鏈路最壞情況 × 安全係數;小於 ExecutionTimeout
WorkflowExecutionTimeout 整體執行上限(含續跑/重試) 跨重啟/重試的整體時間邊界 覆蓋流程最長預期時間;避免設過大難以觀測
WorkflowTaskTimeout 決策任務(Workflow Task)的上限 決策回合/輪詢間的處理 維持小值(數秒);通常用預設即可,避免卡住決策迴圈

3.2 Workflow Timeout 的設定思維

  • 原則:

    • WorkflowTaskTimeout 保持小值(數秒級),避免決策迴圈被長時間占用。
    • 長時間等待不要丟到 Workflow 層;長任務應由 Activity 的 Heartbeat/Checkpoint 管理。
    • WorkflowExecutionTimeout 要能涵蓋流程可能的活動鏈與重試總歷時,RunTimeout 僅限單次 run。
    • 與 Activity Timeout 協調:不要用放大的 WorkflowTaskTimeout 來掩蓋活動端設定不足。
  • 快速檢查:

    • WorkflowExecutionTimeout 是否 ≥ WorkflowRunTimeout?
    • WorkflowTaskTimeout 是否為小值(避免長時間卡住決策迴圈)?
    • 與 Activity Timeout 是否協調(例如:長任務靠 Heartbeat,而非放大 WorkflowTaskTimeout)?
  • 常見錯誤:

    • 把長等待放在 WorkflowTaskTimeout,導致決策迴圈卡住、吞吐下降。
    • 只設 RunTimeout 未設 ExecutionTimeout,流程跨重啟時提前終止或行為不一致。
    • 用過大的 Workflow 層超時掩蓋活動端的 Timeout/Heartbeat 設計不足。

3.3 需要特別設定 Workflow Timeout 的情況

  • 大多數情境無須設定,用預設值即可
  • 有明確時限的流程(SLA/業務規則)
    • 例:「訂單 7 天內要完成,超過自動取消」→ WorkflowExecutionTimeout = 7d
    • 例:「申請審核最多等 30 分鐘」→ WorkflowRunTimeout = 30m
  • 避免 Zombie Workflow(長期掛單)
    • Worker 異常時流程可能長存;設上限便於監控與清理快速發現異常個體。
  • 測試 / POC / Demo
    • 開發/測試環境希望自動超時 fail,免手動 Terminate。

程式碼範例:

// 設定 Workflow 層的超時
WorkflowOptions wfOptions = WorkflowOptions.newBuilder()
    .setTaskQueue("MAIN_TASK_QUEUE")
    .setWorkflowRunTimeout(Duration.ofHours(1))         // 單次 run 上限
    .setWorkflowExecutionTimeout(Duration.ofDays(1))    // 整體上限(含續跑/重試)
    .setWorkflowTaskTimeout(Duration.ofSeconds(10))     // 決策任務小超時(SDK 預設通常足夠)
    .build();

// 建立 Workflow stub
MyWorkflow workflow = client.newWorkflowStub(MyWorkflow.class, wfOptions);

結語

讓等待有邊界,流程才穩定;下一篇接著談 Retry Policy 的參數與實務。


上一篇
Day10 - 重試之前先判斷:錯誤分類與處理路徑設計
下一篇
Day12 - 錯誤難免,重試要有策略:Retry Policy 的設計思維
系列文
Temporal 開發指南:掌握 Workflow as Code 打造穩定可靠的分散式流程14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言