インスタンスライフサイクルフックを実装および構成すると、特定のインスタンスライフサイクルイベントが発生したときに Function Compute が対応するフックを呼び出します。このトピックでは、カスタムイメージのインスタンスライフサイクルフックを実装する方法について説明します。
背景情報
関数インスタンスのライフサイクルには、Initializer フックと PreStop フックが含まれます。Initializer フックには、コードの呼び出しと命令の実行の 2 種類があります。現在、命令の実行タイプの Initializer フックをサポートしているのは、GPU アクセラレーション関数のみです。詳細については、「インスタンスライフサイクルの設定」をご参照ください。
インスタンスライフサイクルフックは、通常の呼び出しリクエストと同じ方法で課金されます。実行ログは [リアルタイムログ]、[関数ログ]、または [高度なログ] にのみ表示され、[呼び出しリクエストリスト] には表示されません。詳細については、「インスタンスライフサイクルフックのログの表示」をご参照ください。
現在、`execute instruction` フックによって生成されたログは、関数ログに書き込むことはできません。
コールバックメソッドの実装
特定のインスタンスライフサイクルイベントが発生すると、Function Compute は対応するフックを呼び出します。インスタンスのライフサイクルには、Initializer フックと PreStop フックが含まれます。Initializer フックには、コードの呼び出しまたは命令の実行の 2 種類があります。一度に設定できる Initializer フックは 1 種類のみです。
コードの呼び出し
`invoke code` フックを設定すると、システムは関数に HTTP リクエストを送信します。インスタンスの起動時に `POST /initialize` リクエストが送信され、インスタンスの停止時に `GET /pre-stop` リクエストが送信されます。ビジネスコードでこれらのリクエストを処理する必要があります。
パス | 入力リクエスト | 期待される応答 |
(オプション) POST |
| 応答本文: 関数の Initializer の戻り値。 状態コード
説明 Initializer フックがタイムアウトまたは失敗した場合、サーバーは常に HTTP 200 状態コードを返します。エラーが初期化の失敗によって引き起こされたかどうかを判断するには、 |
(オプション) GET |
| 応答本文: 関数の PreStop の戻り値。 状態コード
|
カスタムイメージで Initializer フックを使用するには、HTTP サーバーに `POST /initialize` パスのロジックを実装する必要があります。同様に、PreStop フックの場合は、`GET /pre-stop` パスのロジックを実装する必要があります。次の例では、Python 3.10 のカスタムランタイムを使用しています。
関数を作成するときに Initializer フックを構成しない場合は、`/initialize` パスを実装する必要はありません。`/initialize` パスを実装してもフックを構成しない場合、コード内のロジックは呼び出されません。同じことが PreStop フックと `/pre-stop` パスにも当てはまります。
import os
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route('/initialize', methods=['POST'])
def init_invoke():
rid = request.headers.get('x-fc-request-id')
print("FC Initialize Start RequestId: " + rid)
# 独自の処理を記述
print("FC Initialize End RequestId: " + rid)
return "OK"
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def hello_world(path):
rid = request.headers.get('x-fc-request-id')
print("FC invoke Start RequestId: " + rid)
# 独自の処理を記述
print("FC invoke End RequestId: " + rid)
return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]
@app.route('/pre-stop', methods=['GET'])
def prestop_invoke():
rid = request.headers.get('x-fc-request-id')
print("FC PreStop Start RequestId: " + rid)
# 独自の処理を記述
print("FC PreStop End RequestId: " + rid)
return "OK"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000)
上記のコードに加えて、Python では関数実行エラーが発生する可能性があります。次のコードは、/initialize のエラーシナリオの例を示しています。
@app.route('/initialize', methods=['POST'])
def init():
raise Exception("hahaha")
return "OK", 200, []@app.route('/initialize', methods=['POST'])
def init():
return "OK", 404, []命令の実行
関数インスタンスの起動後に初期化操作を実行するためのコールバック命令を構成できます。関数のランタイム環境でサポートされている任意のシェル実装 ( /bin/bash、/bin/sh、/bin/csh、/bin/zsh など) を使用できます。
Function Compute コンソールには、/bin/bash と /bin/sh の 2 つのプリセットシェルが用意されています。次の例では /bin/sh を使用します。
#!/bin/sh
URL="http://localhost:7860"
REQUEST_PATH="sdapi/v1/txt2img"
JSON_DATA='{
"prompt": "",
"steps": 1,
"height": 8,
"width": 8
}'
temp_file=$(mktemp)
trap 'rm -f "$temp_file"' EXIT
if ! http_code=$(curl -s -w "%{http_code}" \
-H "Content-Type: application/json" \
-d "$JSON_DATA" \
-o "$temp_file" \
-X POST "$URL"/"$REQUEST_PATH"); then
echo "{\"status\": \"curl_error\", \"code\": $curl_exit_code}" \
| jq . >&2
exit 1
fi
response=$(<"$temp_file")
echo "http code $http_code"
if [ "$http_code" -eq 200 ]; then
echo "$response" | jq -r '.' || printf "%s\n" "$response"
exit 0
else
echo "$response_body" \
| jq -c 'if type == "object" then . else {raw: .} end' 2>/dev/null \
| jq -s '{status: "http_error", code: $code, response: .[0]}' \
--arg code "$http_code" \
>&2
exit 1
fiコールバック命令の終了コードが 0 の場合、実行は成功です。それ以外の終了コードは失敗を示します。スクリプトで標準エラー (stderr) にエラーメッセージを出力して、エラーの診断に役立てることができます。たとえば、次のコードスニペットは、curl リクエストが失敗した後にエラー情報を出力し、終了コードを 1 に設定する方法を示しています。
if ! http_code=$(curl -s -w "%{http_code}" \
-H "Content-Type: application/json" \
-d "$JSON_DATA" \
-o "$temp_file" \
-X POST "$URL"/"$REQUEST_PATH"); then
echo "{\"status\": \"curl_error\", \"code\": $curl_exit_code}" \
| jq . >&2
exit 1
fiコールバックのエラーコード
コードの呼び出し
エラーコード ID | 説明 |
400 |
|
404 | |
500 | Function Compute はインスタンスを再起動します。 |
命令の実行
命令の終了コードが 0 でない場合、命令は再実行されず、システムはエラーを返します。
ライフサイクルフックの構成
Function Compute コンソールにログインします。左側のナビゲーションウィンドウで、 を選択します。
上部のナビゲーションバーで、リージョンを選択します。[関数] ページで、ターゲット関数をクリックします。
関数の詳細ページで、[設定] タブをクリックします。[インスタンス設定] セクションで、[編集] をクリックします。
[インスタンス設定] パネルで、Initializer フックを構成し、[Initializer タイムアウト] を設定します。
コードの呼び出し

命令の実行
コンソールには、
/bin/bashと/bin/shの 2 つのプリセットシェルが用意されています。
[インスタンス設定] パネルで、PreStop フックを構成し、そのタイムアウトを設定します。次に、[デプロイ] をクリックします。

インスタンスライフサイクルフックのログの表示
現在、`execute instruction` フックによって生成されたログは、関数ログに書き込むことはできません。
[関数ログ] 機能を使用して、フックのログを表示できます。
Function Compute コンソールにログインします。左側のナビゲーションウィンドウで、 を選択します。
上部のナビゲーションバーで、リージョンを選択します。[関数] ページで、ターゲット関数をクリックします。
関数の詳細ページで、[テスト] タブをクリックし、[関数のテスト] をクリックしてから、 を選択します。
[関数ログ] タブで、関数の呼び出しログと Initializer フックのログを表示できます。以下に例を示します。
2024-06-26 10:59:23FC Initialize Start RequestId: 529eab23-9b3a-4ffc-88c8-9a686******* 2024-06-26 10:59:23FC Initialize End RequestId: 529eab23-9b3a-4ffc-88c8-9a686******* 2024-06-26 10:59:25FC Invoke Start RequestId: 1-667b840c-15c49df0-b7dc1******* 2024-06-26 10:59:25FC Invoke End RequestId: 1-667b840c-15c49df0-b7dc1*******各関数インスタンスは一定期間キャッシュされ、すぐには破棄されないため、PreStop フックのログをすぐに表示できない場合があります。PreStop フックをすぐにトリガーするには、関数の構成またはコードを更新します。更新が完了したら、[関数ログ] で PreStop フックのログを表示できます。以下に例を示します。
2024-06-26 11:04:33FC PreStop Start RequestId: c4385899-f071-490e-a8b7-e33c5******* 2024-06-26 11:04:33FC PreStop End RequestId: c4385899-f071-490e-a8b7-e33c5*******