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