本文介紹Go實現函數執行個體生命週期回調的方法。
背景資訊
當您實現並配置函數執行個體生命週期回調後,Function Compute系統將在相關執行個體生命週期事件發生時調用對應的回調程式。函數執行個體生命週期涉及Initializer、PreFreeze和PreStop三種回調。更多資訊,請參見函數執行個體生命週期回調。
函數執行個體生命週期回調程式與正常調用請求計費規則一致,但其執行日誌只能在函數日誌、執行個體日誌或進階日誌中查詢,調用請求列表不會展示回調程式日誌。具體操作,請參見查看執行個體生命週期回呼函數日誌。
回調方法簽名
- 初始化回調程式(Initializer回調)是在函數執行個體啟動成功之後,運行請求處理常式(Handler)之前執行。Function Compute保證在一個執行個體生命週期內,成功且只成功執行一次Initializer回調。例如您的Initializer回調第一次執行失敗了,系統會重試,直到成功為止,然後再執行您的請求處理常式。因此,您在實現Initializer回調時,需要保證它被重複調用時的正確性。
- 預凍結回調程式(PreFreeze回調)在函數執行個體凍結前執行。
- 預停止回調程式(PreStop回調)在函數執行個體銷毀前執行。
function(ctx context.Context)回調方法實現
// 註冊Initializer回調方法
fc.RegisterInitializerFunction(initialize)
// 註冊PreStop回調方法
fc.RegisterPreStopFunction(preStop)
// 註冊PreFreeze回調方法
fc.RegisterPreFreezeFunction(preFreeze)package main
import (
"context"
"log"
"github.com/aliyun/fc-runtime-go-sdk/fc"
"github.com/aliyun/fc-runtime-go-sdk/fccontext"
)
func HandleRequest(ctx context.Context) (string, error) {
return "hello world!", nil
}
func preStop(ctx context.Context) {
log.Print("this is preStop handler")
fctx, _ := fccontext.FromContext(ctx)
fctx.GetLogger().Infof("context: %#v\n", fctx)
}
func preFreeze(ctx context.Context) {
log.Print("this is preFreeze handler")
fctx, _ := fccontext.FromContext(ctx)
fctx.GetLogger().Infof("context: %#v\n", fctx)
}
func initialize(ctx context.Context) {
log.Print("this is initialize handler")
fctx, _ := fccontext.FromContext(ctx)
fctx.GetLogger().Infof("context: %#v\n", fctx)
}
func main() {
fc.RegisterInitializerFunction(initialize)
fc.RegisterPreStopFunction(preStop)
fc.RegisterPreFreezeFunction(preFreeze)
fc.Start(HandleRequest)
} func initialize(ctx context.Context):Initializer回調方法。其中ctx context.Context參數提供了函數執行時的上下文資訊。更多資訊,請參見上下文。func preStop(ctx context.Context):PreStop回調方法。其中ctx context.Context參數提供了函數執行時的上下文資訊。更多資訊,請參見上下文。func preFreeze(ctx context.Context):PreFreeze回調方法。其中ctx context.Context參數提供了函數執行時的上下文資訊。更多資訊,請參見上下文。- func main():運行FC函數代碼的進入點,Go程式必須包含
main函數。通過添加代碼fc.Start(HandleRequest),佈建要求處理常式的執行方法;通過添加代碼fc.RegisterInitializerFunction(initialize),註冊Initializer回調方法。同理,註冊PreStop和PreFreeze回調方法。重要- 上述樣本僅適用於事件請求處理常式(Event Handler)。如果是HTTP請求處理常式(HTTP Handler),您需要將樣本中的
fc.Start(HandleRequest)換成fc.StartHttp(HandleRequest)。 - 註冊生命週期回調方法必須在
fc.Start(HandleRequest)或fc.StartHttp(HandleRequest)之前執行,否則會導致註冊失敗。
- 上述樣本僅適用於事件請求處理常式(Event Handler)。如果是HTTP請求處理常式(HTTP Handler),您需要將樣本中的
配置生命週期回呼函數
通過控制台配置
在Function Compute控制台的FC函數配置中,啟用Initializer回調程式、PreFreeze回調程式和PreStop回調程式。樣本如下。

具體步驟,請參見函數執行個體生命週期。
通過Serverless Devs配置
使用Serverless Devs配置
s.yaml設定檔中添加Initializer 回調程式、PreFreeze 回調程式和PreStop 回調程式。- Initializer回調配置
在function配置下添加initializer和initializationTimeout兩個欄位。
- PreFreeze回調配置
在function配置下添加instanceLifecycleConfig.preFreeze欄位,包括handler和timeout兩個欄位。
- PreStop回調配置
在function配置下添加instanceLifecycleConfig.preStop欄位,包括handler和timeout兩個欄位。
s.yaml檔案中使用預設值"true"時,必須攜帶雙引號。具體的樣本如下所示。
edition: 1.0.0
name: hello-world # 專案名稱
access: default # 密鑰別名
vars: # 全域變數
region: cn-shanghai # 地區
service:
name: fc-example
description: 'fc example by serverless devs'
services:
helloworld: # 業務名稱/模組名稱
component: fc
props: # 組件的屬性值
region: ${vars.region}
service: ${vars.service}
function:
name: golang-lifecycle-hook-demo
description: 'fc example by serverless devs'
runtime: go1
codeUri: ./target
handler: main
memorySize: 128
timeout: 60
initializationTimeout: 60
initializer: "true"
instanceLifecycleConfig:
preFreeze:
handler: "true"
timeout: 30
preStop:
handler: "true"
timeout: 30關於Serverless Devs的YAML配置規範,請參見Serverless Devs常用命令。
查看執行個體生命週期回呼函數日誌
您可以通過函數日誌功能查看回呼函數日誌。
- 登入Function Compute控制台,在左側導覽列,單擊服務及函數。
- 在頂部功能表列,選擇地區,然後在服務列表頁面,單擊目標服務。
- 在函數管理頁面,單擊目標函數名稱,然後在函數詳情頁面,單擊測試函數頁簽。
- 在測試函數頁簽,單擊測試函數,然後選擇。在函數日誌頁簽,您可以查看函數的調用日誌、Initializer回調日誌和PreFreeze回調日誌,樣本如下。
2022-10-09 19:26:17 FunctionCompute dotnetcore3.1 runtime inited. 2022-10-09 19:26:17 FC Initialize Start RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e****** 2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Initialize start 2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Handle initializer: 793ad2f1-9826-4d9a-90d9-5bf39e****** 2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Initialize end 2022-10-09 19:26:17 FC Initialize End RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e****** 2022-10-09 19:26:17 FC Invoke Start RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e****** 2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Handle request: 793ad2f1-9826-4d9a-90d9-5bf39e****** 2022-10-09 19:26:17 FC Invoke End RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e****** 2022-10-09 19:26:17 FC PreFreeze Start RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e****** 2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] PreFreeze start 2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Handle PreFreeze: 793ad2f1-9826-4d9a-90d9-5bf39e****** 2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] PreFreeze end 2022-10-09 19:26:17 FC PreFreeze End RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e******因為每個函數執行個體會緩衝一段時間,不會馬上銷毀,因此不能立即查看PreStop回調日誌。如需快速觸發PreStop回調,可更新函數配置或者函數代碼。更新完成後,再次查看函數日誌,您可以查看PreStop回調日誌。樣本如下。2022-10-09 19:32:17 FC PreStop Start RequestId: 03be685c-378b-4736-8b08-a67c1d***** 2022-10-09 19:32:17 2022-10-09 19:32:17 03be685c-378b-4736-8b08-a67c1d***** [INFO] PreStop start 2022-10-09 19:32:17 2022-10-09 19:32:17 03be685c-378b-4736-8b08-a67c1d***** [INFO] Handle PreStop: 03be685c-378b-4736-8b08-a67c1d***** 2022-10-09 19:32:17 2022-10-09 19:32:17 03be685c-378b-4736-8b08-a67c1d***** [INFO] PreStop end 2022-10-09 19:32:17 FC PreStop End RequestId: 03be685c-378b-4736-8b08-a67c1d*****
樣本程式
Function Compute為您提供了Initializer回調的樣本程式。該樣本為您展示了如何使用Go運行時的Initializer回調來初始化MySQL串連池。在本樣本中,MySQL資料庫配置在函數的環境變數配置中(參考s.yaml)。Initializer回調從環境變數中擷取資料庫配置,建立MySQL串連池並測試連通性。
更多資訊,請參見go-initializer-mysql。