本文介紹Go實現函數執行個體生命週期回調的方法。
背景資訊
當您實現並配置函數執行個體生命週期回調後,Function Compute系統將在相關執行個體生命週期事件發生時調用對應的回調程式。函數執行個體生命週期涉及Initializer和PreStop回調。更多資訊,請參見配置執行個體生命週期。
函數執行個體生命週期回調程式與正常調用請求計費規則一致,但其執行日誌只能在函數日誌、即時日誌或進階日誌中查詢,調用請求列表不會展示回調程式日誌。具體操作,請參見查看執行個體生命週期回呼函數日誌。
如您需要使用PreStop回調,請將fc-runtime-go-sdk升級到v0.1.0及以上版本。
回調方法簽名
初始化回調程式(Initializer回調)是在函數執行個體啟動成功之後,運行請求處理常式(Handler)之前執行。Function Compute保證在一個執行個體生命週期內,成功且只成功執行一次Initializer回調。例如您的Initializer回調第一次執行失敗了,系統會重試,直到成功為止,然後再執行您的請求處理常式。因此,您在實現Initializer回調時,需要保證它被重複調用時的正確性。
預停止回調程式(PreStop回調)在函數執行個體銷毀前執行。
Initializer回調和PreStop回調方法簽名相同,均只有一個Context輸入參數,沒有返回參數。定義如下:
function(ctx context.Context)
回調方法實現
在代碼中實現生命週期回調方法,並使用相應函數進行註冊。三種回調方法的註冊方法如下:
// 註冊Initializer回調方法
fc.RegisterInitializerFunction(initialize)
// 註冊PreStop回調方法
fc.RegisterPreStopFunction(preStop)
樣本程式如下所示。
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 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.Start(HandleRequest)
}
樣本解析如下:
func initialize(ctx context.Context)
:Initializer回調方法。其中ctx context.Context
參數提供了函數執行時的上下文資訊。更多資訊,請參見上下文。func preStop(ctx context.Context)
:PreStop回調方法。其中ctx context.Context
參數提供了函數執行時的上下文資訊。更多資訊,請參見上下文。func main():運行FC函數代碼的進入點,Go程式必須包含
main
函數。通過添加代碼fc.Start(HandleRequest)
,佈建要求處理常式的執行方法;通過添加代碼fc.RegisterInitializerFunction(initialize)
,註冊Initializer回調方法。註冊PreStop回調方法同理。重要註冊生命週期回調方法必須在
fc.Start(HandleRequest)
或fc.StartHttp(HandleRequest)
之前執行,否則會導致註冊失敗。
配置生命週期回呼函數
通過控制台配置
在Function Compute控制台的FC函數配置中,啟用Initializer回調程式和PreStop回調程式。樣本如下。
具體步驟,請參見配置執行個體生命週期。
通過Serverless Devs配置
如果使用Serverless Devs工具,需要在s.yaml
設定檔中添加Initializer 回調程式和PreStop 回調程式。
Initializer回調配置
在function配置下添加initializer和initializationTimeout兩個欄位。
PreStop回調配置
在function配置下添加instanceLifecycleConfig.preStop欄位,包括handler和timeout兩個欄位。
handler欄位需配置為非Null 字元串,在s.yaml
檔案中使用預設值"true"
時,必須攜帶雙引號。
具體的樣本如下所示。
edition: 3.0.0
name: hello-world # 專案名稱
access: default # 密鑰別名
vars: # 全域變數
region: cn-hangzhou # 地區
resources:
hello_world: # 業務名稱/模組名稱
component: fc3 # 組件名稱
props: # 組件的屬性值
region: ${vars.region} # 地區
functionName: "golang-lifecycle-hook-demo"
description: 'this is golang lifecycle'
runtime: "go1"
code: ./
handler: main
memorySize: 128
timeout: 60
instanceLifecycleConfig: # 擴充函數
preStop: # PreStop函數
handler: preStop # 函數入口
timeout: 60 # 逾時時間
initializer:
handler: initialize
timeout: 60
關於Serverless Devs的YAML配置規範,請參見Serverless Devs常用命令。
查看執行個體生命週期回呼函數日誌
您可以通過函數日誌功能查看回呼函數日誌。
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數詳情頁面,選擇測試頁簽,單擊測試函數,然後選擇 。
在函數日誌頁簽,您可以查看函數的調用日誌和Initializer回調日誌,樣本如下。
2024-03-04 17:57:28FC Initialize Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69 2024-03-04 17:57:282024-03-04 09:57:28.192 1-65e59b07-1520da26-bf73bbb91b69 [info] initializer 2024-03-04 17:57:28FC Initialize End RequestId: 1-65e59b07-1520da26-bf73bbb91b69 2024-03-04 17:57:28FC Invoke Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69 2024-03-04 17:57:28FC Invoke End RequestId: 1-65e59b07-1520da26-bf73bbb91b69
因為每個函數執行個體會緩衝一段時間,不會馬上銷毀,因此不能立即查看PreStop回調日誌。如需快速觸發PreStop回調,可更新函數配置或者函數代碼。更新完成後,再次查看函數日誌,您可以查看PreStop回調日誌。樣本如下。
2024-03-04 18:33:26FC PreStop Start RequestId: 93c93603-9fbe-4576-9458-193c8b213031 2024-03-04 18:33:262024-03-04 10:33:26.077 93c93603-9fbe-4576-9458-193c8b213031 [info] preStop 2024-03-04 18:33:26FC PreStop End RequestId: 93c93603-9fbe-4576-9458-193c8b213031
樣本程式
Function Compute為您提供了Initializer回調的樣本程式。該樣本為您展示了如何使用Go運行時的Initializer回調來初始化MySQL串連池。在本樣本中,MySQL資料庫配置在函數的環境變數配置中(參考s.yaml)。Initializer回調從環境變數中擷取資料庫配置,建立MySQL串連池並測試連通性。
更多資訊,請參見go-initializer-mysql。