解密函數計算異步任務能力之任務的狀態及生命周期管理
作者 | 漸意
一、前言
任務系統中有一類很重要的概念,即任務的狀態。其本質是對任務的生命周期管理。細分的狀態有助于在使用時能夠更清楚的了解系統發生了什么內容,便于針對性的根據業務情況進行操作。函數計算 Serverless Task 提供了多種可查詢的狀態,并提供了各狀態間轉移的時間點。在函數的執行層面,函數計算也提供了任務的生命周期管理概念,用戶可以根據需求決定當系統對任務實例進行初始化、回收等一系列動作時的執行邏輯,實現完整的運行時生命周期管理。本文將分別對任務運行狀態及運行時管理這兩個方面的內容進行介紹。
二、任務的狀態及生命周期的管理
1.任務的狀態管理
執行狀態 | 說明 |
Enqueued | 用戶觸發的 Task 異步消息已進入內部隊列,等待處理。 |
Dequeued | Task 異步消息已從函數計算后端服務出隊,等待觸發。 |
Running | Task 調用執行中。 |
Succeeded | Task 調用執行成功。 |
Failed | Task 調用執行失敗。 |
Stopped | Task 調用因用戶 Cancel 而執行終止。 |
Stopping | Task 調用因用戶 Cancel ,嘗試停止任務中。 |
Expired | 您給異步消息配置了有效期,該消息因過期已被丟棄(未觸發)。 |
Invalid | 您的執行因函數或服務被刪除等原因處于無效狀態(未觸發)。 |
Retrying | Task 調用因執行錯誤重試中。 |
當用戶提交任務并收到提交成功的返回后,任務便已經進入系統對其生命周期的管理流程中。一個任務的狀態變更由內部的一個狀態機負責管理,并對外透出狀態支持實時查詢。整個狀態轉換圖如下所示:
圖 1
- 用戶觸發一次任務后,任務入隊,變更為 Enqueued 狀態,并返回觸發成功;
- 任務在函數計算后端服務中出隊,任務變為 Dequeued 狀態;
- 后端會檢查任務配置。如果:
配置了異步消息有效期功能,并且該消息出隊時間與入隊時間之差已超過有效期,則任務被丟棄,變更為 Expired 狀態。任務終止;
任務對應的函數已被刪除,或創建實例出現錯誤,則丟棄消息,任務變更為 Invalid 狀態;
- 檢查后任務正式進入 Running 狀態。此時任務已觸發實際的執行;
- 任務執行完成后,根據返回會變更為以下幾個狀態:
Retrying:用戶配置了重試次數(默認為 3),且任務執行失敗,這時會進入重試中狀態,之后會變更為 Running 狀態;
Failed:任務執行失敗,且超過了重試次數。此時會將任務狀態改為 Failed;
Succeeded:任務執行成功。
- 如果在整個狀態流轉過程用戶觸發 Cancel,則任務會先變更為 Stopping 狀態,并嘗試停止任務執行。當任務停止執行成功后,任務進入 Stopped 狀態。
2.任務運行時管理及生命周期
當任務狀態進入 Running 后,任務的實際執行便已交給函數計算的運行時。在安全性方面,函數計算會按照 VM 對不同賬號進行隔離,同一個賬號下的函數可能運行于同一個 VM 中。VM 內有一個負責管理容器的客戶端,來實際觸發函數的執行,并收集執行結果。用戶的運行實例有幾個不同的狀態:
圖 2
函數計算對上述所有實例狀態變化的過程均提供接口,支持用戶側配置相應的邏輯。
- 創建完成 -> 執行請求階段:支持 Initializer 功能,支持初始化實例操作。用戶可以配置諸如全局變量、連接池初始化等相關操作;
- 執行中 -> 執行完成后 Pause 實例:支持 PreFreeze 接口,支持在函數 Pause 實例前執行用戶側的自定義邏輯;
- 執行中 -> 外部 cancel:函數計算會強制 Restart 用戶實例,在 Restart 前支持 PreStop 接口。用戶可以配置優雅停止的相關邏輯,以便支持 Cancel 時的自定義行為;
- 完成后 Pause -> 銷毀實例:當一段時間沒有請求后,函數計算將銷毀實例。此時會調用 PreStop 接口,用戶可以配置銷毀容器的行為(如關閉連接池等)。
圖 3
3.任務的停止操作
目前階段函數計算支持了停止單一任務的操作。當用戶操作停止時,支持配置 PreStop 接口,在停止前進行一系列的資源回收工作。停止操作用戶可以使用 SDK 或控制臺來進行調用。以 Go 語言為例,停止一次執行的偽代碼如下所示:
import fc "github.com/aliyun/fc-go-sdk"
func CancelJob() {
stopInput := fc.NewStopStatefulAsyncInvocationInput("ServiceName", "FunctionName", "TaskUUID")
output, err := fcClient.StopStatefulAsyncInvocation(stopInput)
...
}
三、總結
Serverless Task 提供了每個任務的狀態細節,并會對這些細節進行實時的持久化。用戶可以根據需要對這些狀態信息進行實時的查詢,并根據執行及業務情況進行相應的操作。在任務的運行階段,函數計算提供了所有實例狀態轉移過程中的相關接口,支持用戶自定義任務執行前后的邏輯。結合 PreStop 功能及 Cancel 停止任務功能,用戶可以方便的實現任務的優雅操作。?