Back to the blog
C:\BLOG\SERVERLESS-NA-PRATICA.TXT

Serverless na prática: como um evento vira resposta, e quando não usar

O que é serverless de verdade, o caminho de uma requisição sem servidor provisionado, dois exemplos com AWS Lambda e os cenários em que um servidor comum ainda ganha.

This article is only available in Portuguese.

Serverless é um nome ruim. Os servidores continuam existindo; a diferença é que não é você quem cuida deles. Você entrega uma função, diz o que deve disparar essa função, e o provedor de nuvem se encarrega de provisionar, escalar, monitorar e desligar a máquina.

Este texto nasceu de um seminário que apresentei em grupo na disciplina de Engenharia de Software, no curso de Análise e Desenvolvimento de Sistemas da UDESC. O deck está em serverless-soft.vercel.app. Aqui eu organizo o conteúdo em formato de artigo e acrescento o que aprendi usando isso fora da sala.

As peças

  • Evento: o que dispara a execução. Uma requisição HTTP, um arquivo enviado, uma mensagem numa fila, um horário agendado.
  • API Gateway: a porta de entrada HTTP. Recebe a requisição, autentica e encaminha para a função certa.
  • Função: a lógica de negócio. Pequena, isolada e sem estado.
  • Banco e armazenamento: onde o estado mora, já que a função não guarda nada entre uma execução e outra. O armazenamento também pode gerar eventos.
  • Provedor: provisiona, escala, monitora e mantém toda a infraestrutura.

Do evento até a resposta

Uma requisição passa por cinco etapas: o usuário envia, o gateway autentica e roteia, a função executa, lê ou grava no banco, e a resposta volta. A função só existe enquanto executa. Terminou o trabalho, o ambiente é liberado.

A consequência mais interessante aparece com carga. Mil requisições simultâneas viram mil execuções em paralelo, sem nenhuma configuração de autoscaling. Num servidor tradicional, esse pico exigiria máquinas que passam o resto do dia ociosas.

Exemplo 1: miniatura a partir de um upload

O caso clássico. Uma imagem chega no S3, o S3 emite um evento, a Lambda gera a miniatura e grava o registro.

thumbnail.py · AWS Lambda
def handler(event, context):
    info = event["Records"][0]["s3"]
    bucket, key = info["bucket"]["name"], info["object"]["key"]

    obj = s3.get_object(Bucket=bucket, Key=key)
    img = Image.open(io.BytesIO(obj["Body"].read()))
    img.thumbnail((200, 200))

    buf = io.BytesIO()
    img.save(buf, format="JPEG")

    # grava em OUTRO bucket: no mesmo, a miniatura dispararia a função de novo
    s3.put_object(Bucket="miniaturas", Key=key, Body=buf.getvalue())
    tabela.put_item(Item={"arquivo": key})

Exemplo 2: um relatório que roda uma vez por dia

Uma regra do EventBridge dispara a função todo dia de manhã. A função consulta as vendas do dia anterior, monta o relatório e guarda no S3.

relatorio.py · AWS Lambda
def handler(event, context):
    ontem = date.today() - timedelta(days=1)
    vendas = consulta_vendas(ontem)
    relatorio = {"data": str(ontem), "total": sum(v["valor"] for v in vendas)}

    s3.put_object(
        Bucket="relatorios",
        Key=f"vendas/{ontem}.json",
        Body=json.dumps(relatorio),
    )
regra de agendamento · EventBridge
cron(0 11 * * ? *)
# minutos horas dia mês dia-da-semana ano
# 11h UTC = 8h em Brasília

O código roda só nos minutos em que o trabalho acontece. Um servidor comum ficaria ligado 24 horas para trabalhar alguns minutos por dia. E repare no fuso: a expressão é em UTC, um erro fácil de cometer e chato de descobrir.

O que se ganha e o que se paga

Ganha
  • Menos infraestrutura para gerenciar
  • Escala automática com a demanda
  • Pagamento pelo uso, sem máquina ociosa
  • Publicação rápida de funcionalidades
Paga
  • Dependência do provedor
  • Limites de tempo e memória por execução
  • Cold start na primeira chamada
  • Depuração difícil num sistema distribuído
  • Custo que cresce com o volume

O cold start merece atenção. Quando a função não tem um ambiente pronto, o provedor precisa criar um antes de executar, e essa primeira chamada pode levar centenas de milissegundos a mais que as seguintes. Para um relatório diário, não importa. Para uma API que precisa responder rápido em toda requisição, importa muito.

Quando faz sentido

A pergunta não é se serverless é melhor. É em qual cenário as características dele ajudam.

Indicado para
  • APIs e back-ends de apps com demanda irregular
  • Processamento de arquivos e imagens
  • Tarefas agendadas e automações
  • Sistemas orientados a eventos
Avalie outra opção quando
  • A aplicação precisa rodar continuamente
  • A latência precisa ser baixa e previsível
  • O processamento passa dos limites de execução
  • A carga é alta e constante: um servidor dedicado sai mais barato

No meu trabalho, o padrão que mais uso é um meio-termo: a aplicação principal roda num servidor comum (Django, filas, banco) e as peças orientadas a evento, como upload de arquivo, ficam em serviços gerenciados como o S3. Um caso parecido aparece no artigo sobre o Ducktix, onde o banco serverless exigiu um driver diferente para conseguir abrir transações.

Resumo

Serverless troca controle de infraestrutura por agilidade e escala automática. O provedor cuida do servidor; o time cuida do código. Resolve ociosidade, picos e provisionamento manual. Cold start, limites de execução e dependência do provedor continuam pesando. É uma escolha de cenário, não um upgrade universal.

Para aprofundar: a página de computação sem servidor da AWS e a documentação sobre o ciclo de vida do ambiente de execução da Lambda, que explica o cold start em detalhe.