ライフサイクルフックを使用すると、関数インスタンスのライフサイクル中の 2 つのタイミング(インスタンス起動後と破棄前)でカスタムロジックを実行できます。このページでは、Java 関数における Initializer フックおよび PreStop フックの実装方法と設定方法について説明します。
ライフサイクルフックを使用して、複数回の呼び出しにわたって高コストな初期化処理を償却できます。
Initializer フック:環境変数からデータベースの認証情報を取得し、接続プールを一度だけ開きます。同じインスタンスでの後続の呼び出しはすべてこの接続を再利用するため、レイテンシとコストを削減できます。
PreStop フック:インスタンスが再利用される前に、データベース接続を閉じたり、メモリ上の状態をフラッシュしたりして、リソースリークを防ぎます。
PHP 関数については、「インスタンスのライフサイクルの設定」をご参照ください。
仕組み
Function Compute は、各インスタンスを次の 3 つのステージで実行します。
| ステージ | 日時 | 実行内容 |
|---|---|---|
| Init | インスタンス起動時(最初の呼び出し前) | Initializer フック(1 回のみ) |
| Invoke | 各リクエスト | ご利用のハンドラ |
| Shutdown | インスタンス破棄直前 | PreStop フック |
Initializer フックの動作:
インスタンスのライフサイクル中に正確に 1 回、インスタンス起動後かつ最初のハンドラ呼び出し前に実行されます。
Initializer フックが失敗した場合、Function Compute は成功するまで再試行し、その後ご利用のハンドラを実行します。
再試行を安全に処理できるよう、フックをべき等性(idempotent)にしてください。たとえば、接続プールを作成する前に既に存在するかどうかを確認し、プールが null でない場合は初期化をスキップします。これにより、フックが再試行された場合でも重複した接続が作成されません。
PreStop フックの動作:
インスタンスが破棄される前に実行されます。
インスタンスは破棄前に一定期間キャッシュされるため、PreStop フックは最後の呼び出し直後に実行されるわけではありません。
課金
ライフサイクルフックの実行は、通常の呼び出しと同様に課金されます。フックの実行ログは Function Logs、Real-time Logs、および Advanced Logs に表示されますが、呼び出しリクエストリストには表示されません。
フックの実装
Initializer フック
FunctionInitializer インターフェイスとその initialize(Context context) メソッドを実装します。
インターフェイス定義:
package com.aliyun.fc.runtime;
import java.io.IOException;
/**
* This is the interface for the initialization operation
*/
public interface FunctionInitializer {
/**
* The interface to handle a function compute initialize request
*
* @param context The function compute initialize environment context object.
* @throws IOException IOException during I/O handling
*/
void initialize(Context context) throws IOException;
}PreStop フック
PreStopHandler インターフェイスとその preStop(Context context) メソッドを実装します。
インターフェイス定義:
package com.aliyun.fc.runtime;
import java.io.IOException;
/**
* This is the interface for the preStop operation
*/
public interface PreStopHandler {
/**
* The interface to handle a function compute preStop request
*
* @param context The function compute preStop environment context object.
* @throws IOException IOException during I/O handling
*/
void preStop(Context context) throws IOException;
}完全な例:両方のフックを備えた StreamRequestHandler
package example;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;
import com.aliyun.fc.runtime.FunctionInitializer;
import com.aliyun.fc.runtime.PreStopHandler;
public class App implements StreamRequestHandler, FunctionInitializer, PreStopHandler {
@Override
public void initialize(Context context) throws IOException {
context.getLogger().info("initialize start ...");
}
@Override
public void handleRequest(
InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
context.getLogger().info("handlerRequest ...");
outputStream.write(new String("hello world\n").getBytes());
}
@Override
public void preStop(Context context) throws IOException {
context.getLogger().info("preStop start ...");
}
}注:InputStreamはデータをチャンク単位で返しますが、OutputStreamはそうではありません。
ライフサイクルフックの設定
Function Compute コンソールの使用
Function Compute コンソール の関数詳細ページで、フックフィールドを [パッケージ名].[クラス名]::[メソッド名] の形式で設定します。

上記の例クラスの場合:
Initializer フック:
example.App::initializePreStop フック:
example.App::preStop
Serverless Devs の使用
s.yaml の function 配下に instanceLifecycleConfig を追加し、initializer および preStop サブキーを設定します。各サブキーには handler と timeout(秒単位)を指定します。
# ------------------------------------
# Official manual: https://manual.serverless-devs.com/user-guide/aliyun/#fc3
# Tips: https://manual.serverless-devs.com/user-guide/tips/
# If you have any questions, join the DingTalk group 33947367 for technical support.
# ------------------------------------
edition: 3.0.0
name: hello-world-app
access: "default"
vars: # The global variables
region: "cn-hangzhou"
resources:
hello_world:
component: fc3
actions:
pre-${regex('deploy|local')}:
- run: mvn package -DskipTests
path: ./
props:
region: ${vars.region}
functionName: "start-java-1xqf"
description: 'hello world by serverless devs'
runtime: "java8"
code: ./target/HelloFCJava-1.0-SNAPSHOT-jar-with-dependencies.jar
handler: example.App::handleRequest
memorySize: 128
timeout: 10
instanceLifecycleConfig: # The extension function
initializer: # The Initializer hook
handler: example.App::initialize
timeout: 60
preStop: # The PreStop hook
handler: example.App::preStop # The function handler
timeout: 60 # The timeout period.YAML 構文の完全なリファレンスについては、「Serverless Devs の一般的なコマンド」をご参照ください。
ライフサイクルフックログの確認
フックログは Function Logs 内の呼び出しログと一緒に表示されますが、呼び出しリクエストリストには表示されません。
Function Compute コンソール にログインします。左側のナビゲーションウィンドウで Functions をクリックします。
上部のナビゲーションバーでリージョンを選択します。Functions ページで、管理対象の関数をクリックします。
関数詳細ページで Test Function タブをクリックし、Test Function をクリックしてから、Logs > Function Logs を選択します。
Initializer ログ:
2024-03-04 17:57:28 FC Initialize Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28 2024-03-04 09:57:28.192 1-65e59b07-1520da26-bf73bbb91b69 [info] initializer
2024-03-04 17:57:28 FC Initialize End RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28 FC Invoke Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28 FC Invoke End RequestId: 1-65e59b07-1520da26-bf73bbb91b69PreStop ログ — フックのトリガー:
関数インスタンスは破棄前に一定期間キャッシュされるため、PreStop ログは即座には表示されません。PreStop をすぐにトリガーするには、関数の構成またはコードを更新してください。更新後、PreStop ログが Function Logs に表示されます。
2024-03-04 18:33:26 FC PreStop Start RequestId: 93c93603-9fbe-4576-9458-193c8b213031
2024-03-04 18:33:26 2024-03-04 10:33:26.077 93c93603-9fbe-4576-9458-193c8b213031 [info] preStop
2024-03-04 18:33:26 FC PreStop End RequestId: 93c93603-9fbe-4576-9458-193c8b213031次のステップ
java11-mysql:環境変数からデータベース構成を取得して MySQL 接続を開く Initializer フックと、それを閉じる PreStop フックを使用したサンプルプログラムです。