O blog da AWS

Usando streaming de resposta com o AWS Lambda Web Adapter para otimizar o desempenho

Por Harold Sun, SSA sênior Serverless, AWS GCR, Xue Jiaqing, arquiteto de soluções, AWS GCR, Su Jie, arquiteto associado de soluções, AWS GCR

 

O AWS Lambda agora oferece suporte ao streaming de respostas do Lambda, que introduz um novo modo de invocação acessível por meio dos URLs da função Lambda. Esse recurso permite que as funções do Lambda enviem conteúdo de resposta em partes sequenciais para o cliente. Ele está disponível para o runtime do Node.js e para os runtime personalizados do Lambda e pode ser acessado usando a API InvokeWithResponseStream no Lambda.

O Lambda Web Adapter, escrito em Rust, serve como um adaptador universal para a API Lambda Runtime e a API HTTP. Ele permite que os desenvolvedores empacotem aplicativos web HTTP 1.1/1.0, como Express.js, Next.js, Flask, SpringBoot ou Laravel, e os implantem no AWS Lambda. Isso substitui a necessidade de modificar o aplicativo web para acomodar os formatos de entrada e saída do Lambda, reduzindo a complexidade da adaptação do código para atender aos requisitos do Lambda.

Ao usar outros runtime gerenciados, como Java, Go, Python ou Ruby, os desenvolvedores podem usar o Lambda Web Adapter para criar aplicativos que suportem o streaming de respostas do Lambda com mais facilidade.

Implementando streaming de resposta com o Lambda Web Adapter

Em geral, você pode considerar o Lambda Web Adapter como uma extensão do Lambda, que é integrado ao ambiente de runtime do Lambda usando a API de extensão Lambda. Ele opera em um espaço de processo independente quando a função Lambda é invocada e serve como um runtime personalizado. Quando a função é executada, o Web Adapter é iniciado junto com o aplicativo web empacotado.

Após a inicialização, ele executa uma verificação de prontidão na porta do aplicativo web configurado a cada 10 ms (o padrão é 8080, mas você pode configurar outras portas usando variáveis de ambiente). Depois de receber uma resposta HTTP com o status “200 OK” do aplicativo web, ele encapsula os parâmetros de invocação do Lambda recebidos de acordo com o protocolo HTTP e envia uma solicitação para o aplicativo web em execução.

Depois que o aplicativo Web responde a essa solicitação, o Adaptador Web formata o conteúdo da resposta de acordo com o formato de resposta da função e o envia ao cliente, concluindo uma invocação da função.

Web adapter architecture

Da mesma forma, o Lambda Web Adapter usa a API Custom Runtime para implementar o streaming de respostas. Ao implementar uma função usando streaming de resposta:

  1. O Web Adapter envia uma solicitação POST para a API de resposta do Lambda Runtime, incluindo o cabeçalho HTTP Lambda-Runtime-Function-Response-Mode com o valor streaming e Transfer-Encoding com o valor chunked:
    POST http://${AWS_LAMBDA_RUNTIME_API}/runtime/invocation/${AwsRequestId}/response
    Lambda-Runtime-Function-Response-Mode: streaming
    Transfer-Encoding: chunked
    Bash
  2. Ele codifica os dados de resposta de acordo com a especificação do protocolo HTTP/1.1 “Chunked Transfer Encoding” e os envia como “Corpo” para a API de resposta do Lambda Runtime.
  3. Depois de montar a resposta e concluir a transmissão de dados, o Web Adapter fecha a conexão de rede subjacente.

Em circunstâncias normais, a conclusão dessas etapas permite o streaming de respostas do Lambda em uma função. No entanto, isso não é suficiente para cenários de aplicativos web. Os aplicativos da Web geralmente precisam enviar códigos de status de resposta HTTP personalizados, cabeçalhos HTTP personalizados e alguns dados de cookies para o cliente. As etapas anteriores atingem apenas o streaming do corpo da resposta e não podem adicionar conteúdo aos cabeçalhos HTTP da resposta.

Para adicioná-los, ao enviar o conteúdo da resposta para a API de resposta, você deve:

  1. Adicione um cabeçalho HTTP Content-Type para especificar o MIME type (tipo de mídia original) da resposta como application/vnd.awslambda.http-integration-response.
  2. Envie os cabeçalhos de resposta personalizados, como código de status HTTP, cabeçalhos de clientes e cookies, no formato JSON.
  3. Envie 8 caracteres NULL como separadores.
  4. Envie o conteúdo da resposta codificado usando o protocolo HTTP 1.1 Chunked Transfer Encoding.

Aqui está um exemplo do formato da resposta:

POST http://${AWS_LAMBDA_RUNTIME_API}/runtime/invocation/${AwsRequestId}/response
Lambda-Runtime-Function-Response-Mode: streaming
Transfer-Encoding: chunked
Content-Type: application/vnd.awslambda.http-integration-response
{
    "statusCode":200,
    "headers":{
        "Content-Type":"text/html",
        "custom-header":"outer space"
    },
    "cookies":[
        "language=xxx",
        "theme=abc"
    ]
}
8 NULL characters
Chunked response body
Bash

Em URLs de funções Lambda, cabeçalhos HTTP de vários valores não são compatíveis. Como resultado, você não pode implementar respostas com cabeçalhos HTTP de vários valores no Lambda Web Adapter.

Usando streaming de resposta com o Lambda Web Adapter

Ao empacotar funções do Lambda usando o formato zip, você deve anexar o Lambda Web Adapter como uma camada e configurar a variável de ambiente AWS_LAMBDA_EXEC_WRAPPER com o valor /opt/bootstrap.

Depois disso, você pode configurar o script de inicialização do aplicativo web como o manipulador da função Lambda. Ao fazer isso, a função é capaz de usar o Lambda Web Adapter, e o aplicativo web pode ser iniciado e executado dentro do ambiente de execução do Lambda.

A variável de ambiente AWS_LAMBDA_EXEC_WRAPPER aponta para o script de bootstrap fornecido pelo Web Adapter para garantir a execução adequada da aplicação web.

Ao usar uma imagem Docker ou imagem OCI para empacotar a função Lambda, você só precisa incluir o pacote binário do Lambda Web Adapter no Dockerfile copiando-o para o diretório /opt/extensions dentro da imagem. Além disso, você deve especificar a porta na qual o aplicativo web escuta definindo a variável de ambiente PORT:

COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.7.0 /lambda-adapter /opt/extensions/lambda-adapter

ENV PORT=3000
Bash

Por padrão, o adaptador Web é chamado usando o modo buffered. Para usar o streaming de resposta como modo de invocação na função, você deve configurar uma variável de ambiente. Especifique o modo de invocação do Web Adapter da função como response_stream:

ENV AWS_LWA_INVOKE_MODE=response_stream
Bash

Devido aos diferentes formatos de dados entre os modos de invocação buffered e  response stream, você deve configurar o AWS_LWA_INVOKE_MODE para ter o mesmo comportamento do InvokeMode especificado nos URLs da função Lambda. Caso contrário, o cliente poderá não processar o conteúdo da resposta corretamente.

Exemplo de streaming de resposta do Lambda

A renderização do lado do servidor (SSR) pode acelerar o tempo de carregamento de um aplicativo React. Com o SSR, o servidor gera as páginas HTML e as envia ao cliente, que renderiza o conteúdo. O navegador executa o processo de hidratação, que “desperta” os componentes estáticos do HTML recebido e os monta no aplicativo React. Isso permite uma resposta mais rápida às interações do usuário e melhora a experiência geral do usuário.

Ao usar o streaming de resposta do Lambda, seu aplicativo pode obter um TTFB mais rápido processando o conteúdo da resposta em partes sequenciais. Isso ajuda a reduzir o tempo necessário para que os dados iniciais sejam enviados do servidor para o cliente, melhorando o desempenho geral.

O processo de hidratação pode causar atrasos, pois o JavaScript do lado do cliente precisa renderizar novamente e reidratar a página após o carregamento inicial. O streaming de resposta do Lambda minimiza a necessidade de hidratação da página inteira, levando a uma melhor experiência do usuário.

O suporte do Next.js 13 para streaming com suspensão complementa o recurso de streaming de resposta Lambda, permitindo que você use SSR e hidratação seletiva. Essa combinação pode levar a maiores melhorias no desempenho e na experiência do usuário de seus aplicativos Next.js.

Este repositório do GitHub demonstra um aplicativo Next.js que oferece suporte ao streaming de respostas do Lambda usando o Web Adapter e o recurso de streaming com suspensão. Use o AWS Serverless Application Model (AWS SAM) para implantar o aplicativo e testar essas otimizações:

git clone git@github.com:aws-samples/lwa-nextjs-response-streaming-example.git
cd lwa-nextjs-response-streaming-example.git

sam build
sam deploy -g --stack-name lambda-web-adapter-nextjs-response-streaming-example
Bash

Depois que o sam deploy for concluído, você poderá acessar o endpoint de URLs da função Lambda fornecido na saída. Aqui está o resultado da demonstração do aplicativo Lambda response Streaming Next.js:

Example output

Cotas e preços

O Web Adapter é um aprimoramento do Lambda e não tem custos adicionais. Você só é cobrado pelo uso da função Lambda com base nos recursos consumidos.

No entanto, o streaming de resposta pode resultar em custos adicionais de rede. Você será cobrado por qualquer parte da resposta que exceda 6 MB. Para obter mais informações, consulte a página de preços.

Há um limite máximo de tamanho de resposta de 20 MB para streaming de resposta do Lambda. Esse é um limite flexível, e você pode solicitar o aumento desse limite criando um ticket de suporte.

A velocidade de resposta do streaming de resposta do Lambda depende do tamanho do corpo da resposta. A taxa de transferência dos primeiros 6 MB não é limitada, mas qualquer parte da resposta além de 6 MB tem uma taxa de transferência máxima de 2 MB/s. Para obter informações mais detalhadas, consulte Limites de largura de banda para streaming de resposta.

Conclusão

O streaming de resposta do Lambda pode melhorar o TTFB para páginas da web. Com o suporte do AWS Lambda Web Adapter, os desenvolvedores podem empacotar com mais facilidade aplicativos web que suportem streaming de resposta do Lambda, aprimorando a experiência do usuário e as métricas de desempenho de seus aplicativos web.

Para obter mais recursos de aprendizado Serverless, visite Serverless Land.

Este artigo foi traduzido do Blog da AWS em Inglês.

 


Sobre o autor

Harold Sun é Senior Serverless SSA

 

 

 

 

Xue Jiaqing é  arquiteto de soluções

 

 

 

 

Su Jie é arquiteto associado de soluções

 

 

 

 

Tradutor

Rodrigo Peres é Arquiteto de Soluções na AWS, com mais de 20 anos trabalhando com arquitetura de soluções, desenvolvimento de sistemas e modernização de sistemas legados.