Pular para o conteudo principal

Semáforos de concorrência por recurso sem fila acidental

Limitar concorrência protege recurso escasso, mas sem regra para o excesso o backend só troca saturação direta por fila escondida e latência crescente.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

O problema

Você percebe que um recurso não aguenta concorrência infinita.

Pode ser:

  • pool
  • provider externo
  • operação pesada de banco
  • CPU local

A reação comum é certa pela metade:

  • coloca um semáforo
  • define N em voo

Mas falta a segunda metade:

  • o que acontece com quem ficou para fora?

Se a resposta for “espera aí”, sem limite nem política, o backend não ficou mais seguro.

Só ficou mais silenciosamente congestionado.

Modelo mental

Semáforo é limite de concorrência.

Fila é decisão de admissão.

Essas duas coisas não são a mesma coisa.

Quando você protege um recurso com concorrência máxima de 20, precisa decidir também o destino da requisição de número 21.

Ela pode:

  • falhar cedo
  • esperar pouco
  • ir para fila explícita
  • cair em caminho degradado

Se ela só espera num limbo interno, a fila existe do mesmo jeito.

Só que agora ninguém a chamou pelo nome.

Exemplo simples

Imagine um serviço que chama um provider lento de antifraude.

Você sabe que mais de 30 chamadas simultâneas derrubam latência e erro.

Então cria um semáforo de 30.

Só que, em pico, chegam 400 requests.

Se as 370 restantes ficarem aguardando:

  • a memória sobe
  • o timeout do request começa a gastar antes de entrar
  • o usuário pega resposta ruim do mesmo jeito

O recurso protegido até ficou menos espancado.

Mas o sistema inteiro agora acumulou espera invisível.

O erro comum

O erro comum é achar que “limitar concorrência” já resolve pressão.

Não resolve.

Ele resolve só uma parte:

  • quantos entram

Ainda falta decidir:

  • quantos esperam
  • por quanto tempo
  • em qual prioridade
  • com qual custo

Outro erro comum é usar o mesmo semáforo para tudo.

Online, repair, replay e trabalho de fundo disputam do mesmo jeito e você perde qualquer controle fino.

O que normalmente ajuda

Normalmente ajuda combinar semáforo com política explícita de overflow:

  • timeout curto de espera
  • fila limitada de verdade
  • rejeição com erro claro
  • caminho degradado
  • prioridade separada por tipo de tráfego

Também ajuda medir:

  • in-flight atual
  • tempo médio de espera
  • quantos foram rejeitados
  • quantos estouraram antes de entrar

Quando esses números não existem, o time costuma descobrir fila acidental chamando isso de “latência estranha”.

Como um senior pensa

Quem já operou recurso escasso costuma perguntar:

  • o que exatamente estou protegendo aqui?
  • quem não entrou deve esperar ou nem deveria ser admitido?
  • essa espera ainda cabe no orçamento de latência?
  • existe diferença entre request online e trabalho de fundo?

Essa linha de raciocínio evita backend que parece controlado, mas só porque esconde backlog dentro do processo.

Ângulo de entrevista

Esse tema aparece em backend, providers externos, bancos quentes e filas internas.

O entrevistador quer ver se você entende:

  • a diferença entre controlar concorrência e aceitar trabalho
  • que semáforo sem política de overflow cria fila implícita
  • que proteger recurso também exige decidir quem perde quando a pressão chega

Resposta forte costuma soar assim:

“Eu usaria semáforo para limitar o recurso, mas não deixaria espera crescer sem regra. Se o excesso não puder virar fila explícita com observabilidade, eu prefiro rejeitar cedo ou degradar, em vez de esconder backlog dentro do request.”

Takeaway direto

Semáforo sem política para o excesso não elimina fila.

Só a torna acidental.

Resumo rápido

O que vale manter na cabeça

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Próximo artigo Contratos de erro e semântica de falha sem exceção genérica para tudo Artigo anterior Schema interno de eventos sem acoplamento acidental

Continue explorando

Artigos relacionados