本文介紹PHP如何實現(xiàn)并應用函數實例生命周期回調方法。

背景信息

當您實現(xiàn)并配置函數實例生命周期回調后,函數計算將在相關實例生命周期事件發(fā)生時調用對應的回調程序。函數實例生命周期涉及Initializer、PreFreeze和PreStop三種回調。當前PHP運行時支持Initializer和PreStop兩種函數實例生命周期回調函數。更多信息,請參見函數實例生命周期回調

函數實例生命周期回調程序與正常調用請求計費規(guī)則一致,但其執(zhí)行日志只能在函數日志實例日志高級日志中查詢,調用請求列表不會展示回調程序日志。具體操作,請參見查看實例生命周期回調函數日志

Initializer回調

Initializer示例

初始化回調程序(Initializer回調)在函數實例啟動成功之后,運行請求處理程序(Handler)之前執(zhí)行。函數計算保證在一個實例生命周期內,成功且最多成功執(zhí)行一次Initializer回調。例如,您的Initializer回調第一次執(zhí)行失敗后系統(tǒng)會重試,直到成功為止,然后再執(zhí)行您的請求處理程序。因此,您在實現(xiàn)Initializer回調時,需要保證其被重復調用時的正確性。

Initializer回調只有一個$context輸入參數,使用方法和事件請求處理程序一樣。

一個最簡單的Initializer回調如下所示。

<?php
function my_initializer($context) {
    $logger = $GLOBALS['fcLogger'];
    $logger->info("hello world");
}
?>            

my_initializer是Initializer回調方法名,需要與您在函數計算控制臺配置的Initializer 回調程序相對應。例如,您為函數配置的Initializer 回調程序main.my_initializer,那么函數計算在配置Initializer屬性后會去加載main.php中定義的my_initializer方法。

方法簽名

  • 輸入參數只有context,包含的信息和事件請求處理程序(handler)的context保持一致。
  • contextinitializerinitializationTimeout兩個信息是為Initializer回調設計,如果使用Initializer功能,會被分別設置為您為函數配置的Initializer 回調程序Initializer 回調超時時間的值,否則為空,且不生效。
  • 無返回值。

PreStop回調

預停止回調程序(PreStop回調)在函數實例銷毀前執(zhí)行,方法簽名同Initializer回調。

如下是preStop回調的具體示例。
<?php

$counter = 0;
function preStop($context) {
    $GLOBALS['fcLogger']->info("preStop ok");
}

function handler($event, $context) {
    global $counter;
    $counter += 2;
    return $counter;
}
?>
您可以在您為函數開通的LogStore中查詢到PreStop函數的日志。比如使用如下格式的語句查詢該函數所有日志。更多信息,請參見查詢回調函數相關日志
<funcName> AND <ServiceName> AND qualifier: <VERSION>

配置生命周期回調函數

通過控制臺配置

您可以在函數計算控制臺FC函數配置中,配置Initializer 回調程序PreStop 回調程序。具體操作步驟,請參見函數實例生命周期。回調格式為[文件名.方法名],例如:
  • Initializer 回調程序設置為index.initialize,表示index.php文件中的initialize方法。
  • PreStop 回調程序設置為index.preStop,表示index.php文件中的preStop方法。
db-php-lifecycle

通過Serverless Devs工具配置

如果使用Serverless Devs工具,需要在s.yaml配置文件中添加Initializer 回調程序PreStop 回調程序
  • Initializer回調配置

    function配置下添加initializerinitializationTimeout兩個字段。

  • PreStop回調配置

    function配置下添加instanceLifecycleConfig.preStop字段,包括handlertimeout兩個字段。

具體的示例如下所示。

edition: 1.0.0         #  命令行YAML規(guī)范版本,遵循語義化版本(Semantic Versioning)規(guī)范
name: hello-world-app  #  項目名稱
access: default        #  密鑰別名

vars:
  region: cn-hangzhou
  service:
    name: php72-mysql    # service名稱
    description: 'hello world by serverless devs' # Service的簡短描述

services:
  helloworld: # 業(yè)務名稱/模塊名稱
    component: fc
    props:
      region: ${vars.region}
      service: ${vars.service}
      function:
        name: php72-mysql                              # function名稱
        description: 'hello world by serverless devs'  # function的簡短描述
        runtime: php7.2                                # 運行時
        codeUri: ./code                                # 代碼位置
        handler: index.handler                         # function執(zhí)行的入口,具體格式和語言相關
        memorySize: 128                                # function的內存規(guī)格
        timeout: 60                                    # function運行的超時時間
        initializationTimeout: 20                      # 初始化方法超時時間
        initializer: index.initialize                  # 初始化方法
        instanceLifecycleConfig:                       # 擴展函數
          preStop:                                     # PreStop函數
            handler: index.pre_stop                    # 函數入口
            timeout: 20                                # 超時時間

關于Serverless Devs的YAML配置規(guī)范,請參見Serverless Devs操作命令

查看實例生命周期回調函數日志

您可以通過函數日志功能查看回調函數日志。

  1. 登錄函數計算控制臺,在左側導航欄,單擊服務及函數
  2. 在頂部菜單欄,選擇地域,然后在服務列表頁面,單擊目標服務。
  3. 函數管理頁面,單擊目標函數名稱,然后在函數詳情頁面,單擊測試函數頁簽。
  4. 測試函數頁簽,單擊測試函數,然后選擇調用日志 > 函數日志
    函數日志頁簽,您可以查看函數的調用日志、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回調日志。如需快速觸發(fā)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*****

示例程序

函數計算為您提供了使用Initializer回調和PreStop回調的MySQL示例程序。在本示例中,Initializer回調函數用于從環(huán)境變量中獲取MySQL數據庫配置,創(chuàng)建MySQL連接并測試連通性,PreStop回調函數負責關閉MySQL連接。

詳細信息,請參見php72-mysql