Limitação de frequência de requisições (Rate Limiting) em Java: visão geral de bibliotecas e ferramentas
\n\nRate limiting (limitação de frequência de requisições) é um mecanismo criticamente importante para proteger serviços web, APIs e microsserviços contra sobrecargas, ataques DDoS e abuso acidental. Em Java, existem várias bibliotecas maduras que implementam diferentes algoritmos: desde um contador simples até sistemas distribuídos complexos. Neste artigo, vamos examinar três abordagens principais: Guava RateLimiter, Bucket4j e Resilience4j, além de discutir suas aplicações.
\n\n1. Guava RateLimiter (simples e leve)
\n\nA biblioteca Google Guava fornece a classe RateLimiter, que implementa o algoritmo Token Bucket (balde de tokens) em modo single-thread. Ela é ideal para uso local em um único processo JVM.
Princípio de funcionamento: O balde é preenchido com tokens a uma taxa específica. Cada requisição consome um ou mais tokens. Se não houver tokens suficientes, a thread é bloqueada ou a requisição é rejeitada.
\n\nExemplo de uso do Guava RateLimiter:
\n\nimport com.google.common.util.concurrent.RateLimiter;\n\npublic class GuavaRateLimiterExample {\n public static void main(String[] args) {\n // Cria um RateLimiter para 10 requisições por segundo\n RateLimiter rateLimiter = RateLimiter.create(10.0);\n\n // Simulação de requisições recebidas\n for (int i = 0; i < 20; i++) {\n // tryAcquire() retorna true se um token for obtido\n if (rateLimiter.tryAcquire()) {\n System.out.println("Requisição " + i + " executada");\n } else {\n System.out.println("Requisição " + i + " rejeitada (limite excedido)");\n }\n }\n }\n}\n\n\nVantagens: Dependência mínima, simplicidade, baixo consumo de memória.
\nDesvantagens: Não é adequado para sistemas distribuídos (não sincroniza entre instâncias).
2. Bucket4j (Token Bucket avançado com suporte a Redis)
\n\nBucket4j é uma biblioteca que implementa o algoritmo Token Bucket com recursos avançados: suporte a vários provedores para armazenamento de estado (in-memory, Redis, Hazelcast, Infinispan), permitindo seu uso em cenários distribuídos.
\n\nCaracterísticas principais:
\n- \n
- Suporte aos modos greedy e interval-based. \n
- Possibilidade de definir limites para diferentes janelas de tempo (por exemplo, 100 requisições por minuto + 10 requisições por segundo). \n
- Integração com Jakarta EE / Spring Boot através de filtros e anotações prontos. \n
Exemplo com armazenamento in-memory:
\n\nimport io.github.bucket4j.Bandwidth;\nimport io.github.bucket4j.Bucket;\nimport io.github.bucket4j.Refill;\n\nimport java.time.Duration;\n\npublic class Bucket4jExample {\n public static void main(String[] args) {\n // Limite: 5 requisições em 10 segundos\n Bandwidth limit = Bandwidth.classic(5, Refill.intervally(5, Duration.ofSeconds(10)));\n Bucket bucket = Bucket.builder()\n .addLimit(limit)\n .build();\n\n for (int i = 0; i < 10; i++) {\n if (bucket.tryConsume(1)) {\n System.out.println("Requisição " + i + " permitida");\n } else {\n System.out.println("Requisição " + i + " bloqueada");\n }\n }\n }\n}\n\n\nVantagens: Configuração flexível, suporte distribuído, alta performance.
\nDesvantagens: Mais dependências do que o Guava.
3. Resilience4j RateLimiter (para arquitetura de microsserviços)
\n\nResilience4j é uma biblioteca para garantir tolerância a falhas, que inclui o módulo RateLimiter. Ela foi projetada levando em consideração
Também na biblioteca
Event Bus e padrão Observer em JavaScript (Node.js): implementação e exemplos