

# Criar um runtime personalizado para AWS Lambda
<a name="runtimes-custom"></a>

É possível implementar um runtime do AWS Lambda em qualquer linguagem de programação. O runtime é um programa que executa um método de manipulador da função do Lambda quando a função é invocada. É possível incluir o runtime no pacote de implantação da função ou distribuí-lo em uma [camada](chapter-layers.md). Ao criar a função do Lambda, escolha um [runtime somente do sistema operacional](runtimes-provided.md) (a família de runtime `provided`).

**nota**  
Criar um runtime personalizado é um caso de uso avançado. Se você estiver procurando informações sobre como compilar em um binário nativo ou usar um runtime pronto para uso de terceiros, consulte [Quando usar runtimes somente para sistema operacional do Lambda](runtimes-provided.md).

Para obter uma explicação passo a passo do processo de implantação de runtime personalizado, consulte [Tutorial: criar um runtime personalizado](runtimes-walkthrough.md).

**Topics**
+ [Requisitos](#runtimes-custom-build)
+ [Implementação do streaming de resposta em um runtime personalizado](#runtimes-custom-response-streaming)
+ [Criação de runtimes personalizados para instâncias gerenciadas do Lambda](#runtimes-custom-managed-instances)

## Requisitos
<a name="runtimes-custom-build"></a>

Os runtimes personalizados devem realizar determinadas tarefas de inicialização e processamento. Um runtime executa o código de configuração da função, lê o nome do manipulador de uma variável de ambiente e lê eventos de invocação da API de runtime do Lambda. O runtime transmite os dados de eventos para o manipulador de funções e publica a resposta do manipulador de volta no Lambda.

### Tarefas de inicialização
<a name="runtimes-custom-initialization"></a>

As tarefas de inicialização são executadas uma vez [ por instância da função ](lambda-runtime-environment.md) a fim de preparar o ambiente para processar invocações.
+ **Recuperar configurações**: leia variáveis de ambiente para obter detalhes sobre a função e o ambiente.
  + `_HANDLER`: a localização do manipulador, da configuração da função. O formato padrão é `file.method`, em que `file` é o nome do arquivo sem uma extensão, e `method` é o nome de um método ou da função que é definido no arquivo.
  + `LAMBDA_TASK_ROOT`: o diretório que contém o código da função.
  + `AWS_LAMBDA_RUNTIME_API`: o host e a porta da API do runtime.

  Para obter uma lista completa das variáveis disponíveis, consulte [Variáveis de ambiente com runtime definido](configuration-envvars.md#configuration-envvars-runtime).
+ **Inicializar a função**: carregar o arquivo do manipulador e executar qualquer código global ou estático que ele contenha. As funções devem criar recursos estáticos como clientes SDK e conexões de banco de dados uma vez e reutilizá-los para várias invocações.
+ **Lidar com erros**: se ocorrer um erro, chame a API [erro de inicialização](runtimes-api.md#runtimes-api-initerror) e saia imediatamente.

A inicialização é considerada no runtime e tempo limite cobrados. Quando uma execução aciona a inicialização de uma nova instância da função, é possível ver o tempo de inicialização nos logs e no [rastreamento do AWS X-Ray](services-xray.md).

**Example log**  

```
REPORT RequestId: f8ac1208... Init Duration: 48.26 ms   Duration: 237.17 ms   Billed Duration: 300 ms   Memory Size: 128 MB   Max Memory Used: 26 MB
```

### Tarefas de processamento
<a name="runtimes-custom-processing"></a>

Enquanto ela é executada, um [ usa a interface de runtime do ](runtimes-api.md) Lambda para gerenciar eventos de entrada e relatar erros. Depois de executar as tarefas de inicialização, o runtime processa eventos de entrada em um loop. No código do seu runtime, execute as seguintes etapas em ordem.
+ **Obter um evento**: chame a API [próxima invocação](runtimes-api.md#runtimes-api-next) para obter o próximo evento. O corpo da resposta contém os dados do evento. Os cabeçalhos da resposta contêm o ID da solicitação e outras informações.
+ **Propagar o cabeçalho de rastreamento**: obtenha o cabeçalho de rastreamento do X-Ray do cabeçalho `Lambda-Runtime-Trace-Id` na resposta da API. Defina a variável de ambiente `_X_AMZN_TRACE_ID` localmente com o mesmo valor. O X-Ray SDK usa esse valor para conectar dados de rastreamento entre serviços.
+ **Criar um contexto de objeto**: crie um objeto com informações de contexto de variáveis do ambiente e cabeçalhos na resposta da API.
+ **Invocar o manipulador de funções**: transmita o evento e o objeto de contexto para o manipulador.
+ **Processar a resposta**: chame a API de [resposta de invocação](runtimes-api.md#runtimes-api-response) para publicar a resposta do manipulador.
+ **Processar erros**: se ocorrer um erro, chame a API [erro de invocação](runtimes-api.md#runtimes-api-invokeerror).
+ **Limpeza**: libere recursos não utilizados, envie dados para outros serviços ou execute tarefas adicionais antes de receber o próximo evento.

### Entrypoint
<a name="runtimes-custom-bootstrap"></a>

O ponto de entrada de um runtime personalizado é um arquivo executável denominado `bootstrap`. O arquivo de bootstrap pode ser o runtime ou ele pode invocar outro arquivo que criará o runtime. Se a raiz do pacote de implantação não contiver um arquivo denominado `bootstrap`, o Lambda procurará o arquivo nas camadas da função. Se o arquivo `bootstrap` não existir ou não for executável, a função retornará um erro de `Runtime.InvalidEntrypoint` na invocação.

Veja um exemplo em que o arquivo `bootstrap` usa um pacote de versão do Node.js para executar um runtime do JavaScript em um arquivo separado denominado `runtime.js`.

**Example bootstrap**  

```
#!/bin/sh
    cd $LAMBDA_TASK_ROOT
    ./node-v11.1.0-linux-x64/bin/node runtime.js
```

## Implementação do streaming de resposta em um runtime personalizado
<a name="runtimes-custom-response-streaming"></a>

Para [funções de streaming de resposta](configuration-response-streaming.md), os endpoints `response` e `error` têm um comportamento ligeiramente modificado que possibilita que o runtime faça o streaming de respostas parciais para o cliente e retorne cargas úteis em blocos. Para obter mais informações sobre o comportamento específico, consulte o seguinte:
+ `/runtime/invocation/AwsRequestId/response`: propaga o cabeçalho `Content-Type` do runtime para enviar ao cliente. O Lambda retorna a carga de resposta em blocos por meio de codificação de transferência em blocos do HTTP/1.1. Para fazer o streaming da resposta para o Lambda, o runtime deve:
  + Definir o cabeçalho HTTP `Lambda-Runtime-Function-Response-Mode` como `streaming`.
  + Defina o cabeçalho `Transfer-Encoding` como `chunked`.
  + Gravar a resposta em conformidade com a especificação de codificação de transferência em blocos HTTP/1.1.
  + Encerrar a conexão subjacente após escrever a resposta com êxito.
+ `/runtime/invocation/AwsRequestId/error`: o runtime pode usar esse endpoint para relatar erros de função ou de runtime ao Lambda, que também aceita o cabeçalho `Transfer-Encoding`. Esse endpoint pode ser chamado somente antes que o runtime comece a enviar uma resposta de invocação.
+ Relatar erros intermediários usando trailers de erro em `/runtime/invocation/AwsRequestId/response`: para relatar erros ocorridos após o runtime começar a gravar a resposta da invocação, o runtime pode, opcionalmente, anexar cabeçalhos HTTP no final, chamados de `Lambda-Runtime-Function-Error-Type` e `Lambda-Runtime-Function-Error-Body`. O Lambda trata isso como uma resposta com êxito e encaminha os metadados de erro fornecidos pelo runtime ao cliente. 
**nota**  
Para vincular cabeçalhos à direita, o runtime deve definir o valor do cabeçalho `Trailer` no início da solicitação HTTP. Isso é um requisito da especificação de codificação de transferência em blocos do HTTP/1.1.
  + `Lambda-Runtime-Function-Error-Type`: o tipo de erro encontrado pelo runtime. Este cabeçalho consiste em um valor de string. O Lambda aceita qualquer string, mas recomendamos um formato *<category.reason>*. Por exemplo, `Runtime.APIKeyNotFound`.
  + `Lambda-Runtime-Function-Error-Body`: informações sobre o erro codificadas em Base64.

## Criação de runtimes personalizados para instâncias gerenciadas do Lambda
<a name="runtimes-custom-managed-instances"></a>

As instâncias gerenciadas do Lambda usam a mesma API de runtime das funções do Lambda (padrão). No entanto, existem diferenças importantes na forma como os runtimes personalizados devem ser implementados para oferecer suporte ao modelo de execução simultânea das instâncias gerenciadas.

### Tratamento simultâneo de solicitações
<a name="runtimes-custom-managed-instances-concurrency"></a>

A principal diferença ao criar runtimes personalizados para instâncias gerenciadas é o suporte a invocações simultâneas. Ao contrário das funções do Lambda (padrão), nas quais o runtime processa uma invocação por vez, as instâncias gerenciadas podem processar várias invocações simultaneamente em um único ambiente de execução.

Seu runtime personalizado deve:
+ **Oferecer suporte a solicitações simultâneas `/next`**: o runtime pode fazer várias chamadas simultâneas para a API de [próxima invocação](runtimes-api.md#runtimes-api-next), até o limite especificado pela variável de ambiente `AWS_LAMBDA_MAX_CONCURRENCY`.
+ **Tratar solicitações simultâneas `/response`**: várias invocações podem chamar a API de [resposta de invocação](runtimes-api.md#runtimes-api-response) simultaneamente.
+ **Implementar o tratamento de solicitações com segurança de thread**: garanta que as invocações simultâneas não interfiram umas nas outras gerenciando adequadamente os recursos e o estado compartilhados.
+ **Usar IDs de solicitação exclusivos**: acompanhe cada invocação separadamente usando o cabeçalho `Lambda-Runtime-Aws-Request-Id` para combinar as respostas com as solicitações correspondentes.

### Padrão de implementação
<a name="runtimes-custom-managed-instances-implementation"></a>

Um padrão de implementação típico para runtimes de instâncias gerenciadas envolve a criação de processos ou threads de operadores para tratar invocações simultâneas:

1. **Ler o limite de simultaneidade**: na inicialização, leia a variável de ambiente `AWS_LAMBDA_MAX_CONCURRENCY` para determinar para quantas invocações simultâneas deve haver suporte.

1. **Criar um grupo de operadores**: inicialize um grupo de operadores (threads, processos ou tarefas assíncronas) igual ao limite de simultaneidade.

1. **Ciclo de processamento do operador**: cada operador, de forma independente:
   + Chama `/runtime/invocation/next` para obter um evento de invocação
   + Invoca o manipulador da função com os dados do evento
   + Publica a resposta em `/runtime/invocation/AwsRequestId/response`
   + Repete o loop

### Considerações adicionais
<a name="runtimes-custom-managed-instances-considerations"></a>
+ **Formato de registro em log**: as instâncias gerenciadas só oferecem suporte ao formato de log JSON. Certifique-se de que seu runtime respeite a variável de ambiente `AWS_LAMBDA_LOG_FORMAT` e use somente o formato JSON. Para obter mais informações, consulte [Configurar logs em formato de texto simples e JSON](monitoring-cloudwatchlogs-logformat.md).
+ **Recursos compartilhados**: tenha cuidado ao usar recursos compartilhados, como o diretório `/tmp` com invocações simultâneas. Implemente mecanismos de travamento adequados para evitar condições de corrida.

Para obter mais informações sobre os ambientes de execução das instâncias gerenciadas do Lambda, consulte [Noções básicas sobre o ambiente de execução das instâncias gerenciadas do Lambda](lambda-managed-instances-execution-environment.md).