Rate Limiting e Throttling em PHP: Domine o fluxo de requisições
\n\nImagine: você lançou uma API incrível para o seu serviço. Tudo funciona perfeitamente, até que um cliente "maluco" começa a bombardear seu servidor com milhares de requisições por segundo. Ou, pior ainda, um bot-parser decide extrair todo o seu banco de dados. Parece familiar? Se não, você teve sorte. Mas é melhor estar preparado. É aqui que entram em cena o rate limiting e o throttling — dois cavaleiros que protegerão seu backend contra sobrecargas.
\n\nNeste artigo, vamos entender como implementar o limite de requisições em PHP, ver exemplos reais de código e descobrir qual método escolher para o seu projeto. Spoiler: você não precisará reinventar a roda, mas conhecer os algoritmos básicos é sempre útil.
\n\nRate Limiting vs Throttling: qual a diferença?
\n\nEsses termos são frequentemente usados como sinônimos, mas existe uma diferença sutil entre eles.
\n\n- \n
- Rate Limiting — é um limite rígido. Você define: "Máximo de 100 requisições por minuto". Quando o limite é atingido, o cliente recebe um HTTP 429 Too Many Requests e é convidado a esperar. \n
- Throttling — é um controle mais suave. Em vez de bloquear, você simplesmente desacelera o processamento das requisições que excedem o limite, colocando-as em uma fila ou reduzindo sua prioridade. \n
Na prática, o throttling em PHP é frequentemente implementado com delays (sleep) ou filas, enquanto o rate limiting usa a contagem de requisições por unidade de tempo. Para a maioria dos gateways de API, a combinação de ambas as abordagens é ideal.
\n\nPor que isso é crucial para o seu projeto?
\n\nExistem pelo menos três motivos para implementar o limite de requisições em PHP:
\n\n- \n
- Proteção contra DDoS e bots — até mesmo um script simples pode derrubar um servidor se a frequência de chamadas não for controlada. \n
- Distribuição justa de recursos — um cliente "ganancioso" não deve prejudicar os demais usuários do serviço. \n
- Estabilidade e previsibilidade — você saberá qual pico de carga esperar e poderá configurar sua infraestrutura adequadamente. \n
Algoritmos de Rate Limiting: escolhendo a estratégia
\n\nAntes de escrever código, vamos analisar três algoritmos populares. Cada um tem seus prós e contras.
\n\n1. Fixed Window (Janela Fixa)
\nA abordagem mais simples. Dividimos o tempo em intervalos (por exemplo, de minuto em minuto). Armazenamos quantas requisições chegaram na janela atual. Se o limite for atingido, bloqueamos até a próxima janela.
\n\nDesvantagem: nas bordas das janelas, pode ocorrer um pico — o cliente pode enviar 100 requisições no final de um minuto e mais 100 no início do próximo, totalizando 200 em 2 segundos.
\n\n2. Sliding Window (Janela Deslizante)
\nUm algoritmo mais preciso. Em vez de intervalos fixos, olhamos para os últimos N segundos. As requisições "envelhecem" e saem da janela. Isso elimina os picos nas bordas.
\n\n3. Token Bucket (Balde de Tokens)
\nUm algoritmo elegante vindo do mundo das redes. Em um "balde" existem tokens. Cada requisição consome um token. Os tokens são reabastecidos a uma taxa definida. Se o balde estiver vazio, a requisição é rejeitada. É ideal para throttling em PHP, pois permite pequenos picos de tráfego.
\n\nImplementação prática: do simples ao avançado
\n\nVamos ao código. Começaremos com um exemplo básico usando arquivos e, em seguida, veremos soluções prontas para produção.
\n\nRate Limiter básico com arquivos (para aprendizado)
\n\nEste exemplo usa arquivos para armazenar contadores. Não é adequado para produção, mas demonstra perfeitamente o conceito.
\n\n<?php\nclass SimpleRateLimiter {\n private string $storageDir;\n private int $maxRequests;\n private int $windowSeconds;\n\n public function __construct(string $storageDir, int $maxRequests = 100, int $windowSeconds = 60) {\n $this->storageDir = rtrim($storageDir, '/') . '/';\n $this->maxRequests = $maxRequests;\n $this->windowSeconds =