Os hooks de ciclo de vida da instância executam sua lógica personalizada quando uma instância de função é iniciada ou interrompida. Este tópico descreve como implementar e configurar os hooks Initializer e PreStop para funções que utilizam imagens personalizadas.
Informações básicas
O ciclo de vida de uma instância de função envolve os hooks Initializer e PreStop. O Function Compute invoca o hook correspondente quando ocorre um evento relacionado ao ciclo de vida da instância.
Existem dois tipos de hook Initializer: invoke code e execute instruction. Atualmente, apenas funções aceleradas por GPU suportam o tipo de hook Initializer execute instruction. Para mais informações, consulte Configure instance lifecycle.
As regras de faturamento para hooks de ciclo de vida da instância são as mesmas aplicadas a solicitações de invocação comuns.
Para mais detalhes sobre logs de hooks, consulte View instance lifecycle hook logs.
Tipos de hooks
Os hooks Initializer suportam dois tipos de implementação. A tabela a seguir os compara.
|
Tipo de hook |
Mecanismo |
Escopo aplicável |
|
invoke code |
O Function Compute envia uma solicitação HTTP para sua função. Seu código de negócio responde à solicitação. |
Hooks Initializer e PreStop |
|
execute instruction |
O Function Compute executa um comando shell ou script configurado por você. O código de saída determina o sucesso ou a falha. |
Apenas hooks Initializer para funções aceleradas por GPU |
Configure apenas um dos dois tipos para um hook Initializer.
Implementar hooks
As seções a seguir descrevem como implementar cada tipo de hook.
Invoke code
Após configurar um hook do tipo invoke code, o Function Compute envia uma solicitação HTTP POST /initialize ou GET /pre-stop para sua função quando uma instância é iniciada ou interrompida. Responda a essa solicitação no seu código de negócio.
Caminho | Solicitação | Resposta esperada |
(Opcional) POST | Corpo da solicitação: Nenhum. Cabeçalhos da solicitação: cabeçalhos comuns. Para mais informações, consulte Function Compute common request headers. | Corpo da resposta: valor retornado pelo Initializer da função. Código de status: 2xx indica sucesso; diferente de 2xx indica falha. Quando um hook Initializer expira ou falha, o servidor sempre retorna o código de status HTTP 200. Utilize o cabeçalho de resposta |
(Opcional) GET | Corpo da solicitação: Nenhum. Cabeçalhos da solicitação: cabeçalhos comuns. Para mais informações, consulte Function Compute common request headers. | Corpo da resposta: valor retornado pelo PreStop da função.
|
A coluna Caminho está marcada como (Opcional) porque cada hook é uma configuração opcional. Caso não defina um Initializer para a função criada, não será necessário implementar /initialize. Nesse cenário, mesmo que seu servidor HTTP implemente /initialize, a lógica de /initialize no seu código nunca será invocada. O mesmo se aplica ao PreStop.
Para utilizar o método de hook Initializer em uma imagem personalizada, implemente a lógica do caminho /initialize com o método POST no seu servidor HTTP. O mesmo procedimento vale para o método de hook PreStop. O programa de exemplo abaixo utiliza o runtime personalizado 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)
Seu código de hook também pode falhar durante a execução. Os exemplos de /initialize a seguir mostram duas falhas típicas e como o Function Compute responde a cada uma delas. Para verificar o comportamento do sistema em relação a cada código de erro, consulte Hook error codes.
No exemplo abaixo, o handler gera uma exceção. O Function Compute trata a falha como um erro 500 e reinicia a instância.
@app.route('/initialize', methods=['POST'])
def init():
raise Exception("hahaha")
return "OK", 200, []
No exemplo seguinte, o handler retorna um código de status 404. O Function Compute não reenvia a solicitação.
@app.route('/initialize', methods=['POST'])
def init():
return "OK", 404, []
Execute instruction (apenas funções aceleradas por GPU)
O tipo execute instruction está disponível apenas para funções aceleradas por GPU.
Com o tipo execute instruction, o Function Compute executa o comando shell ou script configurado após o início da instância da função. Um código de saída 0 indica que a instrução do hook foi executada com sucesso. Qualquer outro código de saída indica falha.
É possível usar uma implementação de shell personalizada, como /bin/bash, /bin/sh, /bin/csh ou /bin/zsh. Certifique-se de que o ambiente de runtime da função suporte a implementação de shell utilizada.
O console do Function Compute oferece /bin/bash e /bin/sh como opções predefinidas. O exemplo a seguir utiliza /bin/sh. O script realiza uma verificação de integridade da inicialização: ele usa curl para enviar uma solicitação a um service local e emprega jq para formatar a saída. Garanta que ambas as ferramentas estejam disponíveis no seu ambiente de runtime.
#!/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
Escreva informações de erro na saída de erro padrão (stderr) no seu script para facilitar a identificação da causa do problema. Por exemplo, o trecho de código a seguir registra informações de erro quando a solicitação curl falha e define o código de saída como 1. O mesmo comportamento de falha se aplica: se a instrução retornar um código de saída diferente de zero, ela não será executada novamente e o sistema retornará o erro relacionado. Para mais informações, 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 de ciclo de vida
Faça login no console do Function Compute. No painel de navegação à esquerda, escolha Function Management > Functions.
Na barra de navegação superior, selecione uma região. Na página Functions, clique em na função desejada.
Na página de detalhes da função, clique em na aba Configuration. Na seção Instance Configuration, clique em Modify.
-
No painel Instance Configuration, configure o hook Initializer. Ative a chave Initializer hook e defina o Initializer timeout conforme suas necessidades de negócio. Neste exemplo, o tempo limite está definido como
300segundos. Para hook type, selecione um dos seguintes tipos:-
invoke code
Ao ativar o hook, o Function Compute envia uma solicitação HTTP POST
/initializepara a função quando a instância é iniciada. Seu código de negócio deve responder à solicitação e retornar o código de status 200. -
execute instruction
Este tipo de hook está disponível exclusivamente para funções aceleradas por GPU.
Selecione execute instruction como tipo de hook e escolha uma instrução shell, como /bin/sh. No editor de código, escreva o script de inicialização. Para um exemplo completo, consulte Execute instruction (GPU-accelerated functions only).
-
(Opcional) Configure o hook PreStop. Ative a chave PreStop hook e defina o PreStop timeout conforme suas necessidades de negócio. Neste exemplo, o tempo limite está definido como
3segundos.Clique em Deploy.
Verifique se os hooks entraram em vigor. Invoque a função ou atualize a configuração ou o código dela para acionar a criação e a destruição da instância. Em seguida, verifique os logs dos hooks seguindo as instruções em View instance lifecycle hook logs.
Visualizar logs de hooks de ciclo de vida da instância
Consulte os logs de execução de hooks em Real-time Log, Function Logs ou Advanced Logs. A Invocation Request List não exibe logs de hooks.
Logs gerados por hooks do tipo execute instruction não podem ser gravados em Function Logs.
Utilize o recurso Function Logs para visualizar os logs dos hooks.
Faça login no console do Function Compute. No painel de navegação à esquerda, escolha Function Management > Functions.
Na barra de navegação superior, selecione uma região. Na página Functions, clique em na função desejada.
-
Na página de detalhes da função, clique em na aba Test, clique em Test Function e escolha Logs > Function Logs.
Na aba Function Logs, visualize os logs de invocação e os logs do hook Initializer da função. O exemplo a seguir mostra os logs.
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*******
Como cada instância de função permanece em cache por um período e não é destruída imediatamente, os logs do hook PreStop não ficam disponíveis instantaneamente. Para acionar o hook PreStop rapidamente, atualize a configuração ou o código da função. Após concluir a atualização, verifique novamente os Function Logs para visualizar os logs do hook PreStop. O exemplo a seguir mostra os logs.
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 erro de hooks
Invoke code
|
Código de erro |
Descrição |
|
400 |
Se um hook Initializer falhar e retornar 400 ou 404, a solicitação não será reenviada, mas o sistema continuará tentando até que a invocação tenha sucesso. Caso um hook PreStop falhe e retorne 400 ou 404, o congelamento e a interrupção da instância da função não serão afetados. |
|
404 |
|
|
500 |
O Function Compute reinicia a instância. |
Execute instruction
Caso a instrução retorne um código de saída diferente de zero, ela não será executada novamente e o sistema retornará o erro relacionado. Se o seu script gravar informações de erro no stderr, utilize essa saída para identificar a causa da falha.