Los hooks del ciclo de vida de instancias ejecutan su lógica personalizada cuando una instancia de función inicia o se detiene. Este tema describe cómo implementar y configurar los hooks Initializer y PreStop para funciones que usan imágenes personalizadas.
Contexto
El ciclo de vida de una instancia de función incluye los hooks Initializer y PreStop. Function Compute invoca el hook correspondiente cuando ocurre un evento relacionado con el ciclo de vida de la instancia.
Un hook Initializer tiene dos tipos: invoke code y execute instruction. Actualmente, solo las funciones aceleradas por GPU admiten el tipo de hook Initializer execute instruction. Para obtener más información, consulte Configure instance lifecycle.
Las reglas de facturación de los hooks del ciclo de vida de instancias son las mismas que aplican a las solicitudes de invocación normales.
Para obtener más información sobre los registros de los hooks, consulte View instance lifecycle hook logs.
Tipos de hooks
Los hooks Initializer admiten dos tipos de implementación. A continuación se comparan ambos.
|
Tipo de hook |
Mecanismo |
Ámbito de aplicación |
|
invoke code |
Function Compute envía una solicitud HTTP a su función. Su código de negocio responde a la solicitud. |
Hooks Initializer y PreStop |
|
execute instruction |
Function Compute ejecuta un comando de shell o un script que usted configura. El código de salida determina si la operación fue correcta o falló. |
Solo hooks Initializer para funciones aceleradas por GPU |
Para un hook Initializer, solo puede configurar uno de estos dos tipos.
Implementar hooks
En las siguientes secciones se describe cómo implementar cada tipo de hook.
Invoke code
Después de configurar un hook del tipo invoke code, Function Compute envía una solicitud HTTP POST /initialize o GET /pre-stop a su función cuando una instancia de función inicia o se detiene. Debe responder a esta solicitud en su código de negocio.
Ruta | Solicitud | Respuesta esperada |
(Opcional) POST | Cuerpo de la solicitud: Ninguna. Encabezados de la solicitud: encabezados comunes. Para obtener más información, consulte Function Compute common request headers. | Cuerpo de la respuesta: el valor que devuelve la función Initializer. Código de estado: 2xx: correcto. Distinto de 2xx: error. Cuando un hook Initializer supera el tiempo de espera o falla, el servidor siempre devuelve el código de estado HTTP 200. Use el encabezado de respuesta |
(Opcional) GET | Cuerpo de la solicitud: Ninguna. Encabezados de la solicitud: encabezados comunes. Para obtener más información, consulte Function Compute common request headers. | Cuerpo de la respuesta: el valor que devuelve la función PreStop.
|
La columna Ruta está marcada como (Opcional) porque cada hook es una configuración opcional. Si no establece un Initializer para la función que crea, no necesita implementar /initialize. En este caso, aunque su servidor HTTP implemente /initialize, la lógica de /initialize en su código nunca se invoca. Lo mismo aplica para PreStop.
Para usar el método de hook Initializer en una imagen personalizada, implemente la lógica de la ruta /initialize con el método POST en su servidor HTTP. Lo mismo aplica para el método de hook PreStop. El siguiente programa de ejemplo usa el runtime personalizado de Python 3.10.
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)
# do your things
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)
# do your things
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)
# do your things
print("FC PreStop End RequestId: " + rid)
return "OK"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000)
Su código de hook también puede fallar durante la ejecución. Los siguientes ejemplos de /initialize muestran dos fallos típicos y cómo responde Function Compute ante cada uno. Para conocer el comportamiento del sistema ante cada código de error, consulte Hook error codes.
En el siguiente ejemplo, el handler genera una excepción. Function Compute trata el fallo como un error 500 y reinicia la instancia.
@app.route('/initialize', methods=['POST'])
def init():
raise Exception("hahaha")
return "OK", 200, []
En el siguiente ejemplo, el handler devuelve un código de estado 404. Function Compute no reenvía la solicitud.
@app.route('/initialize', methods=['POST'])
def init():
return "OK", 404, []
Execute instruction (solo funciones aceleradas por GPU)
El tipo execute instruction solo está disponible para funciones aceleradas por GPU.
Con el tipo execute instruction, Function Compute ejecuta el comando de shell o el script que usted configura después de que inicia la instancia de función. Un código de salida 0 indica que la instrucción del hook se ejecutó correctamente. Cualquier otro código de salida indica un fallo.
Puede usar una implementación de shell personalizada, como /bin/bash, /bin/sh, /bin/csh o /bin/zsh. Compruebe que el entorno de ejecución de la función sea compatible con la implementación de shell que utiliza.
La consola de Function Compute ofrece /bin/bash y /bin/sh como opciones predefinidas. El siguiente ejemplo usa /bin/sh. El script realiza una comprobación de estado de inicialización: usa curl para enviar una solicitud a un servicio local y jq para dar formato a la salida. Compruebe que ambas herramientas estén disponibles en su entorno de ejecución.
#!/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
Escriba la información de error en la salida de error estándar (stderr) dentro de su script para facilitar la identificación de la causa. Por ejemplo, el siguiente fragmento de código escribe información de error cuando la solicitud curl falla y establece el código de salida en 1. El comportamiento ante fallos es el mismo: si la instrucción devuelve un código de salida distinto de cero, no se vuelve a ejecutar y el sistema devuelve el error correspondiente. Para obtener más información, consulte Hook error codes.
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
Configurar hooks del ciclo de vida
Inicie sesión en la consola de Function Compute. En el panel de navegación izquierdo, elija Function Management > Functions.
En la barra de navegación superior, seleccione una región. En la página Functions, haga clic en la función de destino.
En la página de detalles de la función, haga clic en la pestaña Configuration. En la sección Instance Configuration, haga clic en Modify.
-
En el panel Instance Configuration, configure el hook Initializer. Active el interruptor Initializer hook y establezca Initializer timeout según sus necesidades de negocio. En este ejemplo, el tiempo de espera se establece en
300segundos. Para hook type, seleccione uno de los siguientes tipos:-
invoke code
Una vez habilitado el hook, Function Compute envía una solicitud HTTP POST
/initializea la función cuando inicia la instancia. Su código de negocio debe responder a la solicitud y devolver el código de estado 200. -
execute instruction
El tipo execute instruction solo está disponible para funciones aceleradas por GPU.
Seleccione execute instruction como tipo de hook y luego elija una instrucción de shell, como /bin/sh. Escriba el script de inicialización en el editor de código. Para ver un ejemplo completo, consulte Execute instruction (GPU-accelerated functions only).
-
(Opcional) Configure el hook PreStop. Active el interruptor PreStop hook y establezca PreStop timeout según sus necesidades de negocio. En este ejemplo, el tiempo de espera se establece en
3segundos.Haga clic en Deploy.
Compruebe que los hooks surtan efecto. Invoque la función, o actualice su configuración o código, para activar la creación y destrucción de instancias. Después, revise los registros de los hooks siguiendo las instrucciones de View instance lifecycle hook logs.
Consultar los registros de los hooks del ciclo de vida de instancias
Puede consultar los registros de ejecución de los hooks en Real-time Log, Function Logs o Advanced Logs. La lista Invocation Request List no muestra los registros de los hooks.
Los registros generados por los hooks de tipo execute instruction no se pueden escribir en Function Logs.
Utilice la función Function Logs para consultar los registros de los hooks.
Inicie sesión en la consola de Function Compute. En el panel de navegación izquierdo, elija Function Management > Functions.
En la barra de navegación superior, seleccione una región. En la página Functions, haga clic en la función de destino.
-
En la página de detalles de la función, haga clic en la pestaña Test, haga clic en Test Function y luego elija Logs > Function Logs.
En la pestaña Function Logs puede consultar los registros de invocación y los registros del hook Initializer de la función. El siguiente ejemplo muestra dichos registros.
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*******
Cada instancia de función permanece en caché durante un periodo de tiempo y no se destruye de inmediato, por lo que los registros del hook PreStop no están disponibles al instante. Para activar rápidamente el hook PreStop, actualice la configuración o el código de la función. Una vez completada la actualización, vuelva a revisar Function Logs para consultar los registros del hook PreStop. El siguiente ejemplo muestra dichos registros.
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*******
Códigos de error de los hooks
Invoke code
|
Código de error |
Descripción |
|
400 |
Si un hook Initializer de función falla y devuelve 400 o 404, la solicitud no se reenvía, pero el sistema sigue reintentando hasta que la invocación se complete correctamente. Si un hook PreStop de función falla y devuelve 400 o 404, la congelación y detención de la instancia de función no se ven afectadas. |
|
404 |
|
|
500 |
Function Compute reinicia la instancia. |
Execute instruction
Si la instrucción devuelve un código de salida distinto de cero, no se vuelve a ejecutar y el sistema devuelve el error correspondiente. Si su script escribe información de error en stderr, puede usar esa salida para identificar la causa del fallo.