Melhores práticas para trabalhar com funções do AWS Lambda - AWS Lambda

Melhores práticas para trabalhar com funções do AWS Lambda

As melhores práticas a seguir são recomendadas para usar o AWS Lambda:

Para obter mais informações sobre práticas recomendadas para aplicações do Lambda, consulte Application design no Serverless Land. Você também pode entrar em contato com sua equipe de conta da AWS e solicitar uma revisão da arquitetura.

Código da função

  • Separe o manipulador do Lambda da lógica central. Isso permite que você crie uma função mais fácil para teste de unidade. No Node.js isso pode ser semelhante a:

    exports.myHandler = function(event, context, callback) { var foo = event.foo; var bar = event.bar; var result = MyLambdaFunction (foo, bar); callback(null, result); } function MyLambdaFunction (foo, bar) { // MyLambdaFunction logic here }
  • Aproveite a reutilização do ambiente de execução para melhorar a performance da função. Inicialize clientes SDK e conexões de banco de dados fora do manipulador de funções e armazene em cache os ativos estáticos localmente no diretório /tmp. As invocações subsequentes processadas pela mesma instância da função podem reutilizar esses recursos. Isso economiza custos reduzindo o runtime da função.

    Para evitar possíveis vazamentos de dados entre invocações, não use o ambiente de execução para armazenar dados do usuário, eventos ou outras informações com implicações de segurança. Se sua função depende de um estado mutável que não pode ser armazenado na memória dentro do manipulador, considere criar uma função separada ou versões separadas de uma função para cada usuário.

  • Use uma diretiva de keep-alive para manter conexões persistentes. O Lambda limpa conexões ociosas ao longo do tempo. A tentativa de reutilizar uma conexão ociosa ao invocar uma função resultará em um erro de conexão. Para manter sua conexão persistente, use a diretiva keep-alive associada ao runtime. Para obter um exemplo, consulte Reutilizar conexões com keep-alive em Node.js.

  • Use variáveis de ambiente para passar parâmetros operacionais para sua função. Por exemplo, se estiver gravando em um bucket do Amazon S3, em vez fixar no código o nome do bucket em que você está gravando, configure o nome do bucket como uma variável de ambiente.

  • Controle as dependências no pacote de implantação da função. O ambiente de execução do AWS Lambda contém várias bibliotecas, como o AWS SDK for Node.js e os tempos de execução do Python (é possível encontrar uma lista completa: Runtimes do Lambda). Para habilitar o conjunto de recursos e atualizações de segurança mais recente, o Lambda atualizará periodicamente essas bibliotecas. Essas atualizações podem introduzir alterações sutis ao comportamento de sua função do Lambda. Para ter controle total das dependências usadas por sua função, empacote todas as dependências em seu pacote de implantação.

  • Minimize o tamanho do pacote de implantação às necessidades do runtime. Isso reduzirá a quantidade de tempo necessária para que seu pacote de implantação seja obtido por download e desempacotado antes da invocação. Para funções criadas em Java ou .NET Core, evite fazer upload da biblioteca inteira do AWS SDK como parte de seu pacote de implantação. Em vez disso, dependa seletivamente dos módulos que coletam os componentes do SDK necessários (por exemplo, DynamoDB, módulos do SDK do Amazon S3 e bibliotecas principais do Lambda).

  • Reduza o tempo necessário para o Lambda desempacotar pacotes de implantação criados em Java colocando seus arquivos .jar de dependências em um diretório lib/separado. Isso é mais rápido do que colocar todo o código de sua função em um único jar com um grande número de arquivos .class. Para obter instruções, consulte Implantar funções do Lambda em Java com arquivos .zip ou JAR.

  • Minimize a complexidade de suas dependências. Prefira frameworks mais simples que sejam carregados rapidamente no startup do ambiente de execução. Por exemplo, prefira frameworks de injeção de dependência Java (IoC) mais simples, como Dagger ou Guice, em vez de frameworks mais complexos, como o Spring Framework.

  • Evite usar código recursivo em sua função do Lambda, em que a função chame a si mesma automaticamente até que alguns critérios arbitrários sejam atendidos. Isso pode levar a um volume não intencional de invocações da função e a custos elevados. Se você fizer isso acidentalmente, defina a simultaneidade reservada da função como 0 imediatamente para limitar todas as invocações da função, enquanto você atualiza o código.

  • Não use APIs não documentadas e não públicas no código da função Lambda. Para os tempos de execução gerenciados pelo AWS Lambda, o Lambda aplica periodicamente atualizações funcionais e de segurança às APIs internas do Lambda. Essas atualizações internas da API podem ser incompatíveis com versões anteriores, gerando consequências não intencionais, como falhas de invocação, caso sua função tenha dependência nessas APIs não públicas. Consulte a referência da API para obter uma lista de APIs disponíveis publicamente.

  • Escreva um código idempotente. Escrever um código idempotente para suas funções garante que eventos duplicados sejam tratados da mesma maneira. Seu código deve validar eventos adequadamente e lidar corretamente com eventos duplicados. Para obter mais informações, consulte Como torno minha função do Lambda idempotente?.

  • Evite usar o cache do DNS Java. As funções do Lambda já armazenam as respostas de DNS em cache. Se usar outro cache do DNS, você poderá experimentar tempos limite de conexão.

    A classe java.util.logging.Logger pode habilitar indiretamente o cache do DNS da JVM. Para substituir as configurações padrão, defina networkaddress.cache.ttl como 0 antes de inicializar o logger. Exemplo:

    public class MyHandler { // first set TTL property static{ java.security.Security.setProperty("networkaddress.cache.ttl" , "0"); } // then instantiate logger var logger = org.apache.logging.log4j.LogManager.getLogger(MyHandler.class); }

    Para evitar falhas de UnknownHostException, é recomendável definir networkaddress.cache.negative.ttl como 0. Você pode definir essa propriedade para uma função do Lambda com a variável de ambiente AWS_LAMBDA_JAVA_NETWORKADDRESS_CACHE_NEGATIVE_TTL=0.

    Desabilitar o cache do DNS da JVM não desabilita o cache do DNS gerenciado do Lambda.

Configuração da função

  • Os testes de performance de sua função Lambda são uma parte essencial para garantir que você escolha a configuração do tamanho da memória ideal. Qualquer aumento no tamanho da memória dispara um aumento equivalente na CPU disponível para sua função. O uso de memória para sua função é determinado por invocação e pode ser visualizado no Amazon CloudWatch. Em cada invocação, será feita uma entrada de REPORT:, conforme mostrado a seguir:

    REPORT RequestId: 3604209a-e9a3-11e6-939a-754dd98c7be3 Duration: 12.34 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 18 MB

    Ao analisar o campo Max Memory Used:, você poderá determinar se a função precisa de mais memória ou se você provisionou excessivamente o tamanho da memória de sua função.

    Para encontrar a configuração de memória correta para suas funções, recomendamos usar o projeto de código aberto AWS Lambda Power Tuning. Para obter mais informações, consulte AWS Lambda Power Tuning no GitHub.

    Para otimizar a performance da função, também recomendamos a implantação de bibliotecas que possam aproveitar as Advanced Vector Extensions 2 (AVX2). Isso permite processar cargas de trabalho exigentes, incluindo inferência de machine learning, processamento de mídia, High Performance Computing (HPC – Computação de alta performance, simulações científicas e modelagem financeira. Para obter mais informações, consulte Creating faster AWS Lambda functions with AVX2.

  • Teste a carga de sua função do Lambda para determinar um valor de tempo limite ideal. É importante analisar por quanto tempo sua função é executada para que você possa determinar melhor qualquer problema com um serviço de dependência que possa aumentar a simultaneidade da função além do que você espera. Isso é importante, principalmente quando sua função do Lambda faz chamadas de rede para recursos que não podem lidar com a escalabilidade do Lambda.

  • Use permissões mais restritivas ao definir políticas do IAM. Compreenda os recursos e operações necessários para sua função do Lambda e limite a função de execução a essas permissões. Para ter mais informações, consulte Gerenciando permissões no AWS Lambda.

  • Familiarize-se com o Cotas Lambda. O tamanho da carga, os descritores de arquivos e o espaço /tmp geralmente são ignorados ao determinar os limites de recursos de runtime.

  • Exclua as funções do Lambda que você não está mais usando. Fazendo isso, as funções não utilizadas não serão contadas desnecessariamente em relação ao limite do tamanho do pacote de implantação.

  • Se você estiver usando o Amazon Simple Queue Service como uma fonte de eventos, certifique-se de que o valor do tempo de invocação esperado da função não exceda o valor do Tempo limite de visibilidade na fila. Isso se aplica aCreateFunctioneUpdateFunctionConfiguration.

    • No caso de CreateFunction, o AWS Lambda fará com que haja falha no processo de criação da função.

    • No caso de UpdateFunctionConfiguration, isso pode resultar em invocações duplicadas da função.

Escalabilidade de função

  • Conheça suas restrições de throughput de upstream e downstream. Embora as funções do Lambda sejam dimensionadas perfeitamente com a carga, as dependências de upstream e downstream talvez não tenham os mesmos recursos de throughput. Se você precisar definir um limite para a escalabilidade da sua função, é possível configurar a simultaneidade reservada em sua função.

  • Integre a tolerância do controle de utilização. Se sua função síncrona sofrer controle de utilização devido a níveis de tráfego que excedam a taxa de escalabilidade do Lambda, você poderá aplicar as seguintes estratégias para melhorar a tolerância ao controle de utilização:

    • Use tempos-limite, novas tentativas e recuo com jitter. A implementação dessas estratégias desobstrui a repetição de invocações e ajuda a garantir que o Lambda possa aumentar a escala verticalmente em poucos segundos a fim de minimizar o controle de utilização do usuário final.

    • Use simultaneidade provisionada. A simultaneidade provisionada é o número de ambientes de execução previamente inicializados que você deseja que o Lambda aloque à sua função. O Lambda processa as solicitações recebidas usando simultaneidade provisionada, quando disponível. Se for o caso, o Lambda também pode escalar sua função acima e além da configuração de simultaneidade provisionada. A configuração da simultaneidade provisionada gera cobranças adicionais na sua conta da AWS.

Métricas e alarmes

  • UseTrabalhar com métricas de funções Lambda e Alarmes do CloudWatch, em vez de criar ou atualizar uma métrica no código da função do Lambda. É uma forma muito mais eficiente de monitorar a integridade de suas funções do Lambda permitindo detectar problemas no início do processo de desenvolvimento. Por exemplo, é possível configurar um alarme com base na duração esperada da invocação da função do Lambda para lidar com gargalos ou latências atribuíveis ao código da função.

  • Utilize sua biblioteca de logs e as Métricas e dimensões do AWS Lambda para detectar erros de aplicativo (por exemplo, ERR, ERROR, WARNING etc.)

  • Use o AWS Cost Anomaly Detection para detectar atividades incomuns em sua conta. O Cost Anomaly Detection usa machine learning para monitorar continuamente seu custo e uso, minimizando alertas de falsos positivos. O Cost Anomaly Detection usa dados do AWS Cost Explorer, que tem um atraso de até 24 horas. Como resultado, ele pode levar até 24 horas para detectar uma anomalia após a ocorrência do uso. Para começar a usar o Cost Anomaly Detection, primeiro cadastre-se no Explorador de Custos. Em seguida, acesse o Cost Anomaly Detection.

Trabalhar com fluxos

  • Teste com diferentes tamanhos de lotes e de registros para que a frequência de sondagem de cada origem de evento seja ajustada para a rapidez com que a função pode concluir sua tarefa. O parâmetro BatchSize CreateEventSourceMapping controla o número máximo de registros que podem ser enviados para sua função a cada invocação. Um tamanho de lote maior geralmente absorve de maneira mais eficiente a sobrecarga da invocação em um conjunto maior de registros aumentando o throughput.

    Por padrão, o Lambda invoca a função assim que os registros estão disponíveis. Se o lote que o Lambda lê da fonte de eventos tiver apenas um registro, o Lambda enviará apenas um registro à função. Para evitar a invocação da função com poucos registros, instrua a fonte de eventos para armazenar os registros em buffer por até cinco minutos, configurando uma janela de lotes. Antes de invocar a função, o Lambda continua a ler registros da fonte de eventos até coletar um lote inteiro, até que a janela de lote expire ou até que o lote atinja o limite de carga útil de 6 MB. Para ter mais informações, consulte Comportamento de lotes.

    Atenção

    Os mapeamentos da origem do evento do Lambda processam cada evento ao menos uma vez, podendo haver o processamento duplicado de registros. Para evitar possíveis problemas relacionados a eventos duplicados, é altamente recomendável tornar o código da função idempotente. Para saber mais, consulte Como tornar minha função do Lambda idempotente no Centro de Conhecimentos da AWS.

  • Aumente o throughput de processamento de transmissão do Kinesis adicionando fragmentos. Uma transmissão do Kinesis é composto de um ou mais fragmentos. O Lambda sondará cada fragmento com no máximo uma invocação simultânea. Por exemplo, se o seu fluxo tiver 100 estilhaços ativos, haverá, no máximo, 100 invocações de função do Lambda em execução simultaneamente. O aumento do número de estilhaços aumentará diretamente o número máximo de invocações simultâneas de função do Lambda e poderá aumentar o throughput para processamento de transmissões do Kinesis. Se você estiver aumentando o número de fragmentos em uma transmissão do Kinesis, certifique-se de ter escolhido uma boa chave de partição (consulte Chaves de partição) para seus dados, para que os registros relacionados terminem nos mesmos fragmentos e seus dados sejam bem distribuídos.

  • Use o Amazon CloudWatch no IteratorAge para determinar se a transmissão do Kinesis está sendo processada. Por exemplo, configure um alarme do CloudWatch com uma configuração máxima de 30000 (30 segundos).

Melhores práticas de segurança

  • Monitore seu uso do AWS Lambda em relação às práticas recomendadas de segurança com o AWS Security Hub. O Security Hub usa controles de segurança para avaliar configurações de recursos e padrões de segurança que ajudam você a cumprir vários frameworks de conformidade. Para obter mais informações sobre como usar o Security Hub para avaliar os recursos do Lambda, consulte Controles do AWS Lambda no Guia do usuário do AWS Security Hub.

  • Monitore os logs de atividade de rede do Lambda usando a proteção do Lambda do Amazon GuardDuty. A proteção do Lambda ajuda você a identificar possíveis ameaças à segurança nas invocações de funções do Lambda em sua Conta da AWS. Por exemplo, se uma de suas funções consultar um endereço IP associado a atividades relacionadas a criptomoeda. O GuardDuty monitora os logs de atividade de rede gerados mediante a invocação de uma função do Lambda. Para saber mais, consulte Proteção do Lambda no Guia do usuário do Amazon GuardDuty.