O blog da AWS

O AWS Lambda apresenta as APIs de detecção de loop recursivo

Esta publicação foi escrita por James Ngai, gerente sênior de produtos do AWS Lambda, e Aneel Murari, arquiteto de soluções sênior, especialista em Serverless.

Hoje, o AWS Lambda está anunciando novas APIs de detecção de loop recursivo que permitem definir configurações de detecção de loop recursivo individualmente em funções do Lambda. Isso permite que você desative a detecção de loop recursivo em funções que usam padrões recursivos intencionalmente, evitando a interrupção dessas cargas de trabalho. Você pode usar essas APIs para evitar a interrupção de fluxos de trabalho intencionalmente recursivos à medida que o Lambda expande o suporte à detecção de loop recursivo para outros serviços da AWS.

Visão geral

As funções do AWS Lambda são acionadas em resposta a eventos gerados por vários serviços da AWS. Essas funções do Lambda podem interagir com outros serviços da AWS invocando as APIs de serviço correspondentes. Normalmente, o serviço e o recurso que geram o evento acionador são distintos do serviço e do recurso que a função Lambda chama. No entanto, devido a erros de codificação ou problemas de configuração, pode haver situações em que esses dois recursos sejam iguais, levando a um loop infinito ou recursivo. Essas configurações incorretas podem resultar em cargas de trabalho descontroladas, o que pode gerar uso não planejado e cobranças em sua conta da AWS. Por exemplo, uma função Lambda processa mensagens de um tópico do Amazon Simple Notification Service (SNS), mas depois coloca a notificação resultante de volta no mesmo tópico do SNS. Isso causa um loop infinito.

O Lambda fornece uma grade preventiva integrada que detecta e interrompe a execução de funções em um loop recursivo ou infinito entre o Lambda, o Amazon Simple Queue Service (SQS) e o SNS. Esse recurso, conhecido como detecção de loop recursivo, é ativado por padrão para todas as funções do Lambda. Isso serve como um mecanismo de proteção contra uso não intencional e cobrança inesperada de cargas de trabalho descontroladas.

O Lambda usa uma primitiva de cabeçalho de rastreamento do AWS X-Ray chamada “lineage” para rastrear o número de vezes que uma função foi invocada com um evento. Quando o código da sua função envia um evento usando uma versão compatível do AWS SDK, o Lambda incrementa o contador no cabeçalho da linhagem. Se sua função for então invocada com o mesmo evento de acionamento mais de 16 vezes, o Lambda interrompe a próxima invocação desse evento e emite uma métrica RecursiveInvocationsDropped do Amazon CloudWatch. Se a função for invocada de forma síncrona, o Lambda retornará uma RecursiveInvocationException. Para invocações assíncronas, o Lambda envia o evento para uma fila de mensagens mortas (DLQ) ou para um destino em caso de falha, se um estiver configurado.

Você não precisa configurar o rastreamento ativo do X-Ray para que esse recurso funcione. Para obter mais informações sobre esse recurso e um exemplo de cenário, consulte Detecção e interrupção de loops recursivos nas funções do AWS Lambda.

Embora a AWS geralmente desencoraje essa prática devido à possibilidade de cargas de trabalho descontroladas, alguns clientes empregam intencionalmente padrões recursivos em seus fluxos de trabalho. Anteriormente, os clientes que executavam cargas de trabalho que usavam intencionalmente padrões recursivos só podiam cancelar a detecção de loop recursivo por conta entrando em contato com o AWS Support. Com essas novas APIs, os clientes podem desativar seletivamente a detecção de loop recursivo em funções individuais, mantendo essa proteção preventiva para as demais funções em sua conta que não usam código recursivo.

Hoje, estamos introduzindo duas novas ações de API para detecção de loop recursivo:

  • GetFunctionRecursionConfig retorna detalhes sobre a configuração de detecção de loop recursivo de uma função.
  • PutFunctionRecursionConfig define a configuração de detecção de loop recursivo para uma função. Por padrão, a detecção de loop recursivo está ativada para todas as funções.

Como usar as novas APIs de detecção de loop recursivo

Você pode configurar a detecção de loop recursivo para funções do Lambda por meio do console do Lambda, do AWS CLI ou de ferramentas de infraestrutura como código, como AWS CloudFormation, AWS Serverless Application Model (AWS SAM) ou AWS Cloud Development Kit (CDK). Essa nova opção de configuração é compatível com o AWS SAM CLI versão 1.123.0 e o CDK v2.153.0.

Se você desativar a detecção de loop recursivo para uma função, a métrica de RecursiveInvocationsDropped não será mais emitida para essa função.

Desativar a detecção de loop recursivo em sua função significa que o Lambda não impede mais invocações recursivas causadas por configurações incorretas. Isso pode levar ao uso e ao faturamento inesperados da sua conta da AWS. Você deve explorar formas alternativas de arquitetar sua carga de trabalho que não usem padrões recursivos. A AWS recomenda que você tenha cuidado ao desativar esse recurso de proteção.

Definindo a configuração de detecção de loop recursivo em uma função usando o console do Lambda

Você pode definir a configuração de detecção de loop recursivo no console do AWS Lambda:

  1. No console do AWS Lambda, navegue até a página Funções. Selecione a função que usa padrões intencionalmente recursivos.
  2. Selecione Configuração. Você pode encontrar controles de detecção de loop recursivo na seção Simultaneidade e detecção de recursão.

    Controles de detecção de loop recursivo no console do Lambda

  3. A detecção de loop recursivo é ativada por padrão para todas as funções. Você pode alterar a configuração de detecção de loop recursivo de uma função escolhendo Editar.
  4. Para desativar a detecção de loop recursivo para uma função, selecione Permitir loops recursivos e selecione Salvar.

    Configuração para permitir loops recursivos

Definindo a configuração de detecção de loop recursivo usando o AWS CLI

Você pode obter a configuração atual de detecção de loop de recursão de uma função Lambda usando o seguinte comando da CLI:

aws lambda get-function-recursion-config \
--region $AWS_REGION \
--function-name $FUNCTION_NAME

Você pode atualizar a configuração de detecção de loop de recursão para uma função do Lambda usando o seguinte comando da CLI:

aws lambda put-function-recursion-config \
--region $AWS_REGION \
--function-name $FUNCTION_NAME \
--recursive-loop Allow|Terminate

Certifique-se de definir valores apropriados para AWS_REGION e FUNCTION_NAME nos comandos anteriores. Definir o parâmetro put-function-recursion-config como Allow desativa o comportamento padrão de detecção de loops recursivos. Defina esse valor como Terminate para voltar ao comportamento padrão.

Definindo a configuração de detecção de loop recursivo usando o AWS CloudFormation

Você pode controlar a configuração de detecção de loop recursivo para uma função Lambda definindo a propriedade de recurso RecursiveLoop no CloudFormation. Definir o valor dessa propriedade como Allow desativa o comportamento padrão de detecção automática de loops recursivos. Defina essa propriedade como Terminate se quiser retorná-la ao comportamento padrão. O seguinte trecho do CloudFormation mostra RecursiveLoop definido como Allow.

LambdaFunction:
    Type: AWS::Lambda::Function                                                                                                                                                                                    
    Properties:                                                                                                                                                                                       
      Code:                                                                                                                                                                                          
        S3Bucket:S3_BUCKET                                                                                                                                                                            
        S3Key: S3_KEY      
      Handler: com.example.App::handleRequest                                                                                                                                                        
      MemorySize: 1024
      Role:                                                                                                                                                                                          
        Fn::GetAtt:                                                                                                                                                                                  
        - LambdaFunctionRole                                                                                                                                                                         
        - Arn                                                                                                                                                                               
      Runtime: java17
      RecursiveLoop : Allow                                                                                                                                                                                                                                                                           
      Timeout: 20                                                                                                                                                                        
      TracingConfig:                                                                                                                                                                               
        Mode: Active 

Estendendo a detecção de loop recursivo para serviços adicionais da AWS

Atualmente, a detecção de loop recursivo detecta e interrompe loops entre Lambda, SQS e SNS após aproximadamente 16 invocações. O AWS Lambda planeja estender o suporte para detecção de loop recursivo para serviços adicionais da AWS. Usando as APIs, você pode desativar a detecção de loop recursivo para funções específicas que usam padrões recursivos para que elas não sejam afetadas quando o Lambda expandir a detecção de loop recursivo para serviços adicionais da AWS no futuro.

Uma forma de identificar funções que usam padrões recursivos é usando a métrica RecursiveInvocationsDropped do CloudWatch.

  1. Defina um alarme do CloudWatch em todas as funções do Lambda para a métrica RecursiveInvocationsDropped do CloudWatch. Configure o alarme para ser acionado quando a métrica for maior que o limite de zero. Consulte a documentação do CloudWatch para definir alarmes. Você pode usar o seguinte comando CLI para definir esse alarme:
    aws cloudwatch put-metric-alarm --alarm-name lambda-recursive-alarm --metric-name RecursiveInvocationsDropped --namespace AWS/Lambda --statistic Sum --period 60 --threshold 0 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --alarm-actions $arn-of-sns-notification-topic
  2. Quando o Lambda detecta invocações recursivas, ele emitirá a métrica RecursiveInvocationsDropped, que acionará o alarme. Observe que o Lambda só detectará e interromperá invocações recursivas se todos os serviços dentro do loop oferecerem suporte à detecção de loop recursivo.
  3. Navegue até o console do CloudWatch e determine qual função emitiu a métrica RecursiveInvocationsDropped. Na guia Procurar, em Métricas, escolha visualizar as métricas Por nome de função e pesquise RecursiveInvocationsDropped. Isso listará todas as funções que emitiram essa métrica.

    Métrica RecursiveInvocationsDropped

  4. Determine se a recursão é o padrão pretendido para essa função. Nesse caso, use a API de detecção de loop recursivo para desativar a detecção de loop recursivo para essa função.

Conclusão

A detecção de loop recursivo do Lambda detecta e interrompe automaticamente as invocações recursivas entre o Lambda e os serviços compatíveis, evitando cargas de trabalho descontroladas. Na maioria dos casos, você deve arquitetar suas cargas de trabalho para evitar loops recursivos. Em circunstâncias raras e especiais, talvez você queira desativar o comportamento padrão caso a caso. As APIs de detecção de loop recursivo permitem que você defina a configuração de detecção de loop recursivo em funções de forma individual.

Esse recurso está disponível em todas as regiões da AWS em que o Lambda oferece suporte à detecção de loop recursivo.

Para saber mais sobre essas APIs, consulte as Referências da API do AWS Lambda.

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

Esse blog foi traduzido para o Português e o conteúdo original pode ser acessado em: https://aws.amazon.com/pt/blogs/compute/aws-lambda-introduces-recursive-loop-detection-apis/

Autores

Aneel Murarié arquiteto de soluções sênior, especialista em Serverless
James Ngai é gerente sênior de produtos do AWS Lambda

Tradutores e Revisores

Bianca Mota é arquiteta de soluções para o segmento de Startups e iniciou sua jornada na AWS em 2019 ajudando clientes em suas jornadas na nuvem. Além disso, Bianca é parte da comunidade Serverless na AWS e já apresentou sobre o assunto em diversos eventos, como o AWS Summit São Paulo e o AWS re:Invent.

https://www.linkedin.com/in/bianca-smota/ 

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