Pular para o conteúdo principal

Queue-Based Load Leveling

Descrição​

O padrão Queue-Based Load Leveling coloca uma fila entre as tarefas que geram trabalho (produtores) e o serviço que executa esse trabalho (consumidor). Em vez de chamar o serviço de forma síncrona, cada tarefa publica uma mensagem com os dados necessários na fila, que funciona como um buffer durável até que o serviço a retire e processe.

Com isso, a taxa de chegada de requisições deixa de estar acoplada à taxa de processamento. Picos intermitentes de demanda se acumulam na fila e são consumidos no ritmo que o serviço consegue sustentar, o que suaviza a carga e protege tanto o serviço quanto as tarefas que dependem dele.

Várias tarefas, gerando requisições em taxas muito variáveis, podem compartilhar a mesma fila. O número de filas e de instâncias consumidoras pode ser ajustado conforme a demanda, permitindo dimensionar o serviço para a carga média em vez da carga de pico.

Problemas que resolve​

  • Picos de demanda imprevisíveis que sobrecarregam um serviço e o tornam lento ou indisponível.
  • Falhas causadas por contenção quando muitas requisições concorrentes chegam ao mesmo recurso (banco de dados, cache, armazenamento, API de parceiro).
  • Timeouts e throttling no chamador quando o serviço não responde a tempo.
  • Indisponibilidade temporária do serviço afetando diretamente quem gera o trabalho: com a fila, as tarefas continuam publicando mensagens mesmo que o serviço esteja fora do ar.
  • Superprovisionamento de infraestrutura apenas para absorver picos ocasionais.

Quando usar​

  • A carga apresenta picos intermitentes que podem sobrecarregar serviços downstream.
  • É desejável desacoplar a entrada de requisições da capacidade de processamento para ganhar resiliência e controlar custos.
  • O serviço downstream tem limites rígidos de throughput ou aplica throttling ao atingir um limiar.
  • O trabalho pode ser processado de forma assíncrona, sem que o chamador precise de resposta imediata.

Quando evitar​

  • O chamador exige resposta síncrona e de baixa latência.
  • O volume é previsivelmente baixo e estável, de modo que a complexidade da fila traz pouco benefício.
  • A taxa média de produção supera de forma sustentada a capacidade de consumo: a fila só adia o problema, crescendo indefinidamente.

Trade-offs​

GanhoCusto / Risco
Resiliência a picos e a falhas temporárias do serviçoLatência maior entre a submissão e o processamento
Dimensionamento para a carga média, reduzindo custoMais um componente para operar, monitorar e proteger
Escala independente de produtores e consumidoresComunicação de mão única; respostas exigem mecanismo adicional
Isolamento de falhas do processamento em relação à entradaEntrega pelo menos uma vez exige consumidores idempotentes
Throughput controlado e previsível no recurso downstreamOrdem de processamento não garantida com consumidores paralelos

Considerações adicionais:

  • Controle de taxa: limite a taxa agregada dos consumidores. Autoescalar consumidores sem esse limite apenas transfere a sobrecarga para as dependências downstream. Teste sob carga e ajuste o número de filas e de instâncias.
  • Profundidade da fila: monitore o tamanho e a idade das mensagens; escale consumidores dentro de limites seguros ou descarte/rejeite trabalho no produtor quando necessário.
  • Durabilidade: escolha uma fila que persista mensagens em armazenamento durável ou replicado e conheça suas cotas de tamanho e retenção; avalie recuperação geográfica se necessário.
  • Idempotência: como a maioria das filas entrega mensagens pelo menos uma vez, o processamento repetido deve produzir o mesmo resultado (sem registros duplicados ou cobranças repetidas).
  • Mensagens problemáticas: direcione mensagens que falham de forma persistente para uma dead-letter queue e monitore-a para investigação e reenvio.
  • Ordenação: se for obrigatória, use recursos como sessões ou partições ordenadas (por exemplo, message sessions no Azure Service Bus); caso contrário, projete consumidores para tratar mensagens em qualquer ordem.
  • Respostas: se o produtor precisar de retorno, combine com uma fila de resposta ou com o padrão Asynchronous Request-Reply.

Diagrama​

Várias tarefas publicam mensagens em ritmos irregulares na mesma fila, que absorve os picos; o serviço consome as mensagens no próprio ritmo e protege o recurso downstream, enquanto mensagens que não podem ser processadas são isoladas em uma dead-letter queue.

Padrões relacionados​

  • Competing Consumers — várias instâncias consomem da mesma fila para aumentar o throughput do processamento.
  • Throttling — limita o consumo de recursos; o load leveling evita que a demanda atinja o limiar de throttling.
  • Rate Limiting — controla a taxa com que os consumidores acessam o recurso downstream.
  • Priority Queue — permite processar mensagens mais importantes antes das demais.
  • Asynchronous Request-Reply — oferece um meio de devolver respostas ao chamador em fluxos assíncronos.
  • Idempotent Consumer — garante que mensagens entregues mais de uma vez não causem efeitos duplicados.
  • Claim Check — reduz o tamanho das mensagens enfileiradas armazenando o payload fora da fila.
  • Retry — trata falhas transitórias ao publicar ou processar mensagens.

Referência​