Pular para o conteúdo

apps/patterns/rate-limiter

025 · Padrões Fundamentais · ≈ 5 min de estudo

Rate Limiter

Limita quantas requisições cada cliente faz numa janela deslizante, com o estado no Redis. Todas as instâncias do serviço contam na mesma janela, então o limite configurado é o limite real, não N vezes ele. Use para proteger uma API contra abuso e dividir a capacidade entre clientes.

passos
6
arquivos
6
teste
1
tecnologias
5
Infraestrutura realTypeScriptBunElysiaRedisDocker
Baixar cartão

Cenário

Um banco digital expõe a API de transferências em duas instâncias atrás de um balanceador. Cada conta pode iniciar 3 transferências por segundo, somando as duas instâncias. A conta ACC-1001 dispara 6 transferências alternando as instâncias: as 3 primeiras passam e as 3 seguintes recebem 429. Um segundo depois, as entradas antigas saem da janela e a conta volta a transferir.

Planta

Sequência
8/8
POST /transfers (x-account-id)1EVAL: remove fora da janela, conta, registra2permitido, restam 23200 com RateLimit-*4POST /transfers5EVAL no mesmo sorted set6negado, a mais antiga sai em 1 s7429 com Retry-After: 18Cliente ACC-1001Instância 7020Instância 7021Redis (sorted set por conta)
8

8 passos — reproduza para seguir o fluxo

Como funciona

6 passos

Token bucket limita requisições por janela.

Esconde cada passo: lembre antes de tocar para revelar.

Vocabulário compartilhado

  1. 01

    Chave pela contaA rota é autenticada, então a chave é a conta (transfer:limit:v1:<conta>), nunca o IP

  2. 02

    Janela deslizanteUm sorted set por conta, com o timestamp da requisição como score

  3. 03

    Passo atômicoUm script Lua remove o que saiu da janela, conta e registra; duas instâncias nunca deixam passar a mesma vaga

  4. 04

    Contrato da respostaRateLimit-Limit, RateLimit-Remaining e RateLimit-Reset em toda resposta; 429 com Retry-After quando nega

  5. 05

    Recusa não contaRequisição negada não entra no sorted set, então martelar o limite não empurra a janela

  6. 06

    Fail-closedTransferência é escrita; sem Redis, a API responde 503 em vez de liberar sem limite

apps/patterns/rate-limiter

6 arquivos

src/

  • limit_transfer.tsConexão ao Redis, script Lua da janela deslizante e cabeçalhos RateLimit-*
  • api_transfer.tsAPI Elysia de transferência com o limite por conta no onBeforeHandle
  • config_transfer.tsLê e valida o ambiente no boot
  • limit_transfer.test.tstesteIntegração contra Redis real: fronteira da cota e da janela, corrida entre instâncias, 429
  • demo.tsdemoSobe duas instâncias e alterna transferências entre elas

./

  • docker.shinfraSobe o Redis

Executar · com Docker

  1. ./docker.sh up# sobe Redis
  2. cp .env.example .env# variáveis de ambiente
  3. bun install# dependências
  4. bun run demo# roda o cenário

Testes: bun run test.

Requisitos
BunDocker
Sobe junto
Redis

Por que se relacionam

Teste rápido

Qual é o próximo passo depois de Rate Limiter?

Próximo projeto · Padrões FundamentaisResilience Kit
Esc

↑ ↓ navegarEnter abrir191 resultados