Usar a API de extensões do Lambda para criar extensões - AWS Lambda

Usar a API de extensões do Lambda para criar extensões

Autores de funções do Lambda usam extensões para integrar o Lambda às suas ferramentas preferidas para monitoramento, observabilidade, segurança e governança. Os autores de funções podem usar extensões da AWS, de parceiros da AWS e de projetos de código aberto. Para obter mais informações, consulte Introducing AWS Lambda Extensions no AWS Compute Blog. Esta seção descreve como usar a API de extensões do Lambda, o ciclo de vida do ambiente de execução do Lambda e a referência de API de extensões do Lambda.

A API de extensões e a API de telemetria conectam Lambda e as extensões externas.

Como um autor de extensões, você pode usar as API de extensões do Lambda para integrar profundamente no ambiente de execução do Lambda. Sua extensão pode inscrever-se para eventos de ciclo de vida do ambiente de execução e função. Em resposta a esses eventos, você pode iniciar novos processos, executar lógica e controlar e participar de todas as fases do ciclo de vida do Lambda: inicialização, invocação e desligamento. Além disso, você pode usar os API Runtime Logs para receber um stream de logs.

Uma extensão externa é executada como um processo independente no ambiente de execução e continua a ser executada após a invocação da função ser totalmente processada. Como as extensões são executadas como processos, elas podem ser escritas em uma linguagem diferente da função. Recomendamos que você implemente as extensões usando uma linguagem compilada. Nesse caso, a extensão é um binário autônomo compatível com os tempos de execução compatíveis. Todos os Runtimes do Lambda são compatíveis com extensões. Se você usar uma linguagem não compilada, inclua um runtime compatível na extensão.

O Lambda também oferece suporte a extensões internas. Uma extensão interna é executada como um thread separado no processo de runtime. O runtime inicia e interrompe a extensão interna. Uma maneira alternativa de se integrar com o ambiente do Lambda é usar variáveis de ambiente com linguagem específica e scripts wrapper. Você pode usar isso para configurar o ambiente do runtime e modificar o comportamento de startup do processo do runtime.

Você pode adicionar extensões a uma função de duas maneiras. Para uma função implantada como um arquivo.zip, você implanta a extensão como uma camada. Para uma função definida como uma imagem de contêiner, você adiciona as extensões à imagem do contêiner.

nota

Por exemplo, extensões e scripts de wrapper, consulte AWS Lambda Extensões no repositório AWS Samples GitHub.

Ciclo de vida do ambiente de execução do Lambda

O ciclo de vida do ambiente de execução inclui as seguintes fases:

  • Init: nessa fase, o Lambda cria ou descongela um ambiente de execução com os recursos configurados, faz download do código da função e de todas as camadas, inicializa todas as extensões e o runtime, em seguida executa o código de inicialização da função (o código fora do handler principal). OInitocorre durante a primeira invocação, ou antes de invocações de função se você tiver habilitadoSimultaneidade provisionada.

    OInité dividida em três subfases:Extension init,Runtime init, eFunction init. Essas subfases garantem que todas as extensões e o runtime concluam suas tarefas de configuração antes que o código da função seja executado.

  • Invoke: Nesta fase, o Lambda chama o manipulador de função. Depois que a função é executada até a conclusão, o Lambda se prepara para manipular outra invocação de função.

  • Shutdown: Esta fase é acionada se a função do Lambda não receber quaisquer invocações por um período de tempo. Na fase Shutdown, o Lambda encerra o runtime, alerta as extensões para permitir que elas parem de forma limpa e, em seguida, remove o ambiente. O Lambda envia umShutdownpara cada extensão, que informa a extensão que o ambiente está prestes a ser encerrado.

Cada fase começa com um evento do serviço do Lambda para o runtime e para todas as extensões registradas. O runtime e cada conclusão do sinal de extensão enviando uma Solicitação de API Next. O Lambda congela o ambiente de execução quando cada processo é concluído e não há eventos pendentes.

Ciclo de vida do ambiente de execução do Lambda

Fase de inicialização

Durante oExtension init, cada extensão precisa se registrar com o Lambda para receber eventos. O Lambda usa o nome completo do arquivo da extensão para validar que a extensão concluiu a sequência de bootstrap. Portanto, cada chamada de API Register deve incluir o cabeçalho Lambda-Extension-Name com o nome de arquivo completo da extensão.

É possível registrar até 10 extensões para uma função. Esse limite é imposto pela chamada de API Register.

Depois que cada extensão é registrada, o Lambda inicia a fase Runtime init. O processo de runtime chama functionInit para iniciar a fase Function init.

A fase Init é concluída após o runtime e cada extensão registrada indica a conclusão enviando uma solicitação de API Next.

nota

As extensões podem concluir sua inicialização em qualquer momento da fase Init.

Sequência de eventos na fase de inicialização do Lambda

Fase de invocação

Quando uma função do Lambda é invocada em resposta a uma solicitação de API Next, o envia um evento Invoke para o runtime e para cada extensão registrada para o evento Invoke.

Durante a invocação, as extensões externas são executadas em paralelo com a função. Elas também continuam em execução após a conclusão da função. Isso permite que você capture informações para diagnóstico ou para enviar logs, métricas e rastreamentos para um local de sua escolha.

Depois de receber a resposta da função do runtime, o Lambda retorna a resposta ao cliente, mesmo que as extensões ainda estejam em execução.

A fase Invoke termina após o runtime e todas as extensões sinalizam que elas foram concluídas enviando uma solicitação de API Next.

Sequência de eventos na fase de invocação do Lambda

Carga útil do evento: o evento enviado para o runtime (e a função do Lambda) leva toda a solicitação, os cabeçalhos (como RequestId) e carga útil. O evento enviado para cada extensão contém metadados que descrevem o conteúdo do evento. Este evento de ciclo de vida inclui o tipo do evento, o tempo em que a função timas-out (deadlineMs) requestId, o nome de recurso da Amazon (ARN) da função chamada e cabeçalhos de rastreamento.

As extensões que desejam acessar o corpo do evento de função podem usar um SDK no runtime que se comunica com a extensão. Os desenvolvedores de funções usam o SDK no runtime para enviar a carga útil para a extensão quando a função é invocada.

Veja um exemplo de carga útil:

{ "eventType": "INVOKE", "deadlineMs": 676051, "requestId": "3da1f2dc-3222-475e-9205-e2e6c6318895", "invokedFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:ExtensionTest", "tracing": { "type": "X-Amzn-Trace-Id", "value": "Root=1-5f35ae12-0c0fec141ab77a00bc047aa2;Parent=2be948a625588e32;Sampled=1" } }

Limite de duração: a definição do tempo limite da função limita a duração de toda a fase Invoke. Por exemplo, se você definir o tempo limite da função como 360 segundos, a função e todas as extensões precisam ser concluídas em até 360 segundos. Observe que não há fase de pós-invocação independente. A duração é o tempo total até a conclusão do seu runtime e das invocações de todas as extensões. Esse valor não é calculado até que a função e todas as extensões tenham terminado a execução.

Impacto na performance e sobrecarga de extensão: as extensões podem afetar a performance da função. Como autor da extensão, você tem controle sobre o impacto de performance da extensão. Por exemplo, se a extensão executa operações com uso intenso de computação, a duração da função aumenta, pois a extensão e o código da função compartilham os mesmos recursos de CPU. Além disso, se a extensão executar operações extensas após a conclusão da invocação da função, a duração da função aumentará porque a fase Invoke continuará até que todas as extensões sinalizem que foram concluídas.

nota

O Lambda aloca a potência da CPU em proporção à configuração de memória da função. Você pode ver maior duração de execução e inicialização em configurações de memória mais baixas porque os processos de função e extensão estão competindo pelos mesmos recursos da CPU. Para reduzir a duração da execução e inicialização, tente aumentar a configuração de memória.

Para ajudar a identificar o impacto na performance apresentado pelas extensões na fase Invoke, o Lambda gera a métrica PostRuntimeExtensionsDuration. Essa métrica mede o tempo cumulativo gasto entre a solicitação de API Next do runtime e a última solicitação de API Next da extensão. Para medir o aumento da memória usada, use a métrica MaxMemoryUsed. Para obter mais informações sobre métricas de funções, consulte Uso de métricas do CloudWatch com o Lambda.

Os desenvolvedores de funções podem executar diferentes versões de suas funções lado a lado para entender o impacto de uma extensão específica. Recomendamos que os autores de extensão publiquem o consumo esperado de recursos para facilitar aos desenvolvedores de funções a escolha de uma extensão adequada.

Fase de desligamento

Quando o Lambda estiver prestes a encerrar o runtime, ele enviará um Shutdown a cada extensão externa registrada. As extensões podem usar esse tempo para tarefas de limpeza finais. O evento Shutdown é enviado em resposta a uma solicitação de API Next.

Limite de duração: a duração máxima da fase Shutdown depende da configuração das extensões registradas:

  • 0 ms: uma função sem extensões registradas

  • 500 ms: uma função com uma extensão interna registrada

  • 2.000 ms: uma função com uma ou mais extensões externas registradas

Para uma função com extensões externas, o Lambda reserva até 300 ms (500 ms para um runtime com uma extensão interna) para que o processo de runtime execute um desligamento normal. Lambda aloca o restante do limite de 2.000 ms para extensões externas para desligar.

Se o runtime ou uma extensão não responder ao evento Shutdown dentro do limite, o Lambda encerrará o processo usando um sinal SIGKILL.

Sequência de eventos na fase de encerramento do Lambda

Carga útil do evento: o evento Shutdown contém o motivo do desligamento e o tempo restante em milissegundos.

O shutdownReason inclui os seguintes valores:

  • SPINDOWN: desligamento normal

  • TIMEOUT: limite da duração do tempo expirado

  • FAILURE: condição de erro, como um evento out-of-memory

{ "eventType": "SHUTDOWN", "shutdownReason": "reason for shutdown", "deadlineMs": "the time and date that the function times out in Unix time milliseconds" }

Permissões e configuração

As extensões são executadas no mesmo ambiente de execução que a função do Lambda. As extensões também compartilham recursos com a função, como CPU, memória e armazenamento em disco /tmp. Além disso, as extensões usam a mesma função do AWS Identity and Access Management (IAM) e o mesmo contexto de segurança que a função.

Permissões de acesso ao sistema de arquivos e à rede: as extensões são executadas no mesmo sistema de arquivos e namespace de nome de rede que o runtime da função. Isso significa que as extensões precisam ser compatíveis com o sistema operacional associado. Se uma extensão exigir regras adicionais de saída do tráfego de rede, você deverá aplicar essas regras à configuração da função.

nota

Como o diretório de código de função é somente leitura, as extensões não podem modificar o código da função.

Variáveis de ambiente: as extensões podem acessar as variáveis de ambiente da função, exceto as seguintes variáveis específicas do processo de runtime:

  • AWS_EXECUTION_ENV

  • AWS_LAMBDA_LOG_GROUP_NAME

  • AWS_LAMBDA_LOG_STREAM_NAME

  • AWS_XRAY_CONTEXT_MISSING

  • AWS_XRAY_DAEMON_ADDRESS

  • LAMBDA_RUNTIME_DIR

  • LAMBDA_TASK_ROOT

  • _AWS_XRAY_DAEMON_ADDRESS

  • _AWS_XRAY_DAEMON_PORT

  • _HANDLER

Tratamento de falhas

Falhas de inicialização: se uma extensão falhar, o Lambda reiniciará o ambiente de execução para impor um comportamento consistente e incentivar falhas rapidamente para extensões. Além disso, para alguns clientes, as extensões devem atender às necessidades críticas, como registro em log, segurança, governança e coleta de telemetria.

Invocar falhas (como falta de memória, tempo limite da função): como as extensões compartilham recursos com o runtime, elas são afetadas pelo esgotamento da memória. Quando o runtime falha, todas as extensões e o próprio runtime participam da fase Shutdown. Além disso, o runtime é reiniciado automaticamente como parte do chamado atual ou por meio de um mecanismo de reinicialização adiado.

Se houver uma falha (como um erro de tempo limite ou de runtime de uma função) durante Invoke, o serviço Lambda executará uma redefinição. A redefinição se comporta como um evento Shutdown. Primeiro, o Lambda encerra o runtime, depois, envia um evento Shutdown para cada extensão externa registrada. O evento inclui o motivo do desligamento. Se esse ambiente for usado para uma nova invocação, a extensão e o runtime serão reinicializados como parte da próxima invocação.

Exemplo de ambiente de execução: inicialização, invocação, invocação com erro, invocação, encerramento

Para obter uma explicação mais detalhada do diagrama anterior, consulte Falhas durante a fase de invocação.

Logs de extensões: o Lambda envia a saída de log de extensões para o CloudWatch Logs. O Lambda também gera um evento de log adicional para cada extensão duranteInit. O evento de log registra o nome e a preferência de registro (evento, configuração) em caso de sucesso ou o motivo da falha em caso de falha.

Solução de problemas de extensões

  • Se uma solicitação Register falhar, o cabeçalho Lambda-Extension-Name na chamada de API Register deverá conter o nome completo do arquivo da extensão.

  • Se a solicitação Register falhar para uma extensão interna, a solicitação não deverá estar registrada para o evento Shutdown.

Referência de API de extensões

A especificação OpenAPI para a versão da API de extensões 2020-01-01 está disponível aqui: extensions-api.zip

É possível recuperar o valor do endpoint da API da variável de ambiente AWS_LAMBDA_RUNTIME_API. Para enviar uma solicitação Register, use o prefixo 2020-01-01/ antes de cada caminho da API. Por exemplo:

http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/register

Inscreva-se

DuranteExtension init, todas as extensões precisam se registrar no Lambda para receber eventos. O Lambda usa o nome completo do arquivo da extensão para validar que a extensão concluiu a sequência de bootstrap. Portanto, cada chamada de API Register deve incluir o cabeçalho Lambda-Extension-Name com o nome de arquivo completo da extensão.

As extensões internas são iniciadas e interrompidas pelo processo de runtime, portanto, elas não têm permissão para se registrar para o evento Shutdown.

Caminho: /extension/register

MétodoPOST

Cabeçalhos de solicitação

  • Lambda-Extension-Name: o nome completo do arquivo da extensão. Obrigatório: sim. Tipo: string

  • Lambda-Extension-Accept-Feature: use isso para especificar os recursos opcionais de extensões durante o registro. Obrigatório: não Tipo: strings separada por vírgula. Recursos disponíveis para serem especificados usando essa configuração:

    • accountId: se especificado, a resposta de registro da extensão conterá o ID da conta associada à função do Lambda para a qual você está registrando a extensão.

Parâmetros do corpo da solicitação
  • events: matriz dos eventos para registrar. Obrigatório: não Tipo: matriz de strings. Strings válidas: INVOKE, SHUTDOWN.

Cabeçalhos de resposta
  • Lambda-Extension-Identifier: identificador de agente exclusivo gerado (string UUID) que é obrigatório para todas as solicitações subsequentes.

Códigos de resposta
  • 200: o corpo de resposta contém o nome da função, a versão da função e o nome do manipulador.

  • 400: solicitação inválida

  • 403: proibido

  • 500: erro de contêiner. Estado não recuperável. A extensão deve sair imediatamente.

exemplo Exemplo de corpo da solicitação
{ 'events': [ 'INVOKE', 'SHUTDOWN'] }
exemplo Exemplo de corpo da resposta
{ "functionName": "helloWorld", "functionVersion": "$LATEST", "handler": "lambda_function.lambda_handler" }
exemplo Exemplo de corpo de resposta com recurso opcional accountId
{ "functionName": "helloWorld", "functionVersion": "$LATEST", "handler": "lambda_function.lambda_handler", "accountId": "123456789012" }

Próximo

As extensões enviam uma solicitação de API Next para receber o próximo evento, que pode ser um evento Invoke ou um evento Shutdown. O corpo da resposta contém a carga útil, que é um documento JSON com dados do evento.

A extensão envia uma solicitação de API Next para sinalizar que está pronta para receber novos eventos. Essa é uma chamada de bloqueio.

Não defina um tempo limite na chamada GET, pois a extensão pode ser suspensa por um período até que haja um evento a ser retornado.

Caminho: /extension/event/next

MétodoGET

Cabeçalhos de solicitação
  • Lambda-Extension-Identifier: identificador exclusivo para extensão (string UUID). Obrigatório: sim. Tipo: string UUID.

Cabeçalhos de resposta
  • Lambda-Extension-Event-Identifier: identificador exclusivo para o evento (string UUID).

Códigos de resposta
  • 200: a resposta contém informações sobre o próximo evento (EventInvoke ou EventShutdown).

  • 403: proibido

  • 500: erro de contêiner. Estado não recuperável. A extensão deve sair imediatamente.

Erro de inicialização

A extensão usa esse método para relatar um erro de inicialização para o Lambda. Chame-a quando a extensão falhar ao inicializar após ter sido registrada. Depois que o Lambda recebe o erro, não há mais chamadas de API bem-sucedidas. A extensão deve sair depois de receber a resposta do Lambda.

Caminho: /extension/init/error

MétodoPOST

Cabeçalhos de solicitação
  • Lambda-Extension-Identifier: identificador exclusivo para extensão. Obrigatório: sim. Tipo: string UUID.

  • Lambda-Extension-Function-Error-Type: tipo de erro encontrado pela extensão. Obrigatório: sim. Este cabeçalho consiste em um valor de string. Lambda aceita qualquer string, mas recomendamos o formato <category.reason>. Por exemplo:

    • Extension.NoSuchHandler

    • Extension.APIKeyNotFound

    • Extension.ConfigInvalid

    • Extension.UnknownReason

Parâmetros do corpo da solicitação
  • ErrorRequest: informações adicionais sobre o erro. Obrigatório: não

Este campo é um objeto JSON com a seguinte estrutura:

{ errorMessage: string (text description of the error), errorType: string, stackTrace: array of strings }

Observe que o Lambda aceita qualquer valor para errorType.

O exemplo a seguir mostra uma mensagem de erro de função do Lambda na qual a função não pôde analisar os dados do evento fornecidos na chamada.

exemplo Erro de função
{ "errorMessage" : "Error parsing event data.", "errorType" : "InvalidEventDataException", "stackTrace": [ ] }
Códigos de resposta
  • 202: aceito

  • 400: solicitação inválida

  • 403: proibido

  • 500: erro de contêiner. Estado não recuperável. A extensão deve sair imediatamente.

Erro de saída

A extensão usa esse método para relatar um erro ao Lambda antes de sair. Chame-a quando encontrar uma falha inesperada. Depois que o Lambda recebe o erro, não há mais chamadas de API bem-sucedidas. A extensão deve sair depois de receber a resposta do Lambda.

Caminho: /extension/exit/error

MétodoPOST

Cabeçalhos de solicitação
  • Lambda-Extension-Identifier: identificador exclusivo para extensão. Obrigatório: sim. Tipo: string UUID.

  • Lambda-Extension-Function-Error-Type: tipo de erro encontrado pela extensão. Obrigatório: sim. Este cabeçalho consiste em um valor de string. Lambda aceita qualquer string, mas recomendamos o formato <category.reason>. Por exemplo:

    • Extension.NoSuchHandler

    • Extension.APIKeyNotFound

    • Extension.ConfigInvalid

    • Extension.UnknownReason

Parâmetros do corpo da solicitação
  • ErrorRequest: informações adicionais sobre o erro. Obrigatório: não

Este campo é um objeto JSON com a seguinte estrutura:

{ errorMessage: string (text description of the error), errorType: string, stackTrace: array of strings }

Observe que o Lambda aceita qualquer valor para errorType.

O exemplo a seguir mostra uma mensagem de erro de função do Lambda na qual a função não pôde analisar os dados do evento fornecidos na chamada.

exemplo Erro de função
{ "errorMessage" : "Error parsing event data.", "errorType" : "InvalidEventDataException", "stackTrace": [ ] }
Códigos de resposta
  • 202: aceito

  • 400: solicitação inválida

  • 403: proibido

  • 500: erro de contêiner. Estado não recuperável. A extensão deve sair imediatamente.