Um framework Go abrangente para implementar e testar algoritmos de rate limiting. Este projeto fornece implementações de exemplo de várias estratégias de rate limiting, juntamente com ferramentas cliente-servidor para validação e benchmarking.
Este projeto consiste em:
- Cliente de Teste: Envia requisições a taxas configuráveis
- Servidor de Teste: Atua como um servidor de eco
- Exemplos de Algoritmos: 4 implementações diferentes de rate limiting
- Iniciar o servidor:
go run server/main.go -protocol tcp -port 8080- Em outro terminal, iniciar o cliente:
go run main.go -server localhost:8080 -rate 100 -duration 30s# Iniciar servidor TCP com log detalhado
go run server/main.go -protocol tcp -port 8080 -verbose
# Teste de alta taxa (1000 req/s, 10 conexões)
go run main.go -rate 1000 -connections 10 -duration 60s
# Teste de protocolo UDP
go run server/main.go -protocol udp -port 9090
go run main.go -protocol udp -server localhost:9090 -rate 500.
├── main.go # Cliente de teste
├── server/
│ └── main.go # Servidor de teste
└── sample/
├── token_bucket/ # Implementação token bucket
├── fixed_window/ # Implementação janela fixa
├── sliding_window/ # Implementação janela deslizante
└── concurrent/ # Implementação concurrent-safeUm cliente de teste de rate limiting de alto desempenho.
Recursos:
- Suporte a protocolos TCP/UDP
- Múltiplas conexões concorrentes (apenas TCP)
- Tamanho de mensagem personalizável
- Exibição de estatísticas em tempo real
Opções de Linha de Comando:
-server string # Endereço do servidor (padrão "localhost:8080")
-protocol string # Protocolo: tcp ou udp (padrão "tcp")
-rate int # Mensagens por segundo (padrão 100)
-duration duration # Duração do teste (padrão 10s)
-connections int # Conexões concorrentes, apenas TCP (padrão 1)
-size int # Tamanho da mensagem em bytes (padrão 64)Exemplo de Saída:
Iniciando cliente de teste de rate limit
Protocolo: tcp
Servidor: localhost:8080
Taxa: 1000 mensagens/segundo
Duração: 30s
Conexões: 10
Tamanho da mensagem: 64 bytes
--- Estatísticas do Teste ---
Duração: 30s
Mensagens enviadas: 30000
Mensagens bem-sucedidas: 29850
Mensagens falhadas: 150
Taxa de sucesso: 99,50%
Taxa real: 1000,00 mensagens/segundoUm servidor simples que ecoa mensagens recebidas.
Recursos:
- Suporte a protocolos TCP/UDP
- Múltiplas conexões simultâneas de clientes
- Exibição de estatísticas a cada 5 segundos
- Encerramento gracioso (Ctrl+C)
Opções de Linha de Comando:
-protocol string # Protocolo: tcp ou udp (padrão "tcp")
-port int # Porta de escuta (padrão 8080)
-verbose # Habilitar log detalhadoExemplo de Exibição de Estatísticas:
[15:30:45] Recebidas: 5023, Processadas: 5023, Erros: 0, Taxa: 1004,60 msg/s
[15:30:50] Recebidas: 10089, Processadas: 10089, Erros: 0, Taxa: 1013,20 msg/sRecursos:
- Permite processamento em rajada
- Mantém taxa média permitindo picos de curto prazo
- Eficiente em memória
Exemplo de Uso:
limiter := NewTokenBucket(100, 10) // Capacidade 100, recarga 10/segundo
if limiter.Allow() {
// Processar requisição
}Casos de Uso:
- Rate limiting de API
- Controle de largura de banda de rede
- Quando tráfego em rajada é aceitável
Recursos:
- Implementação simples
- Uso mínimo de memória
- Problemas de limite nas bordas da janela
Exemplo de Uso:
limiter := NewFixedWindowLimiter(1000, time.Minute) // 1000 requisições por minuto
if limiter.Allow() {
// Processar requisição
}Casos de Uso:
- Quando rate limiting simples é necessário
- Performance é priorizada sobre precisão
Recursos:
- Rate limiting mais preciso
- Resolve problemas de limite da janela fixa
- Uso de memória ligeiramente maior
Exemplo de Uso:
limiter := NewSlidingWindowLimiter(100, time.Minute) // 100 requisições por minuto
if limiter.Allow() {
// Processar requisição
}Casos de Uso:
- Quando rate limiting preciso é necessário
- Justiça é importante
Recursos:
- Alto desempenho com operações atômicas
- Suporte a ambiente distribuído
- Exemplo de middleware HTTP
Uso de Middleware HTTP:
// Rate limiting por usuário
userLimiters := &UserRateLimiters{
limiters: make(map[string]*ConcurrentTokenBucket),
limit: 100, // 100 requisições/minuto por usuário
}
mux := http.NewServeMux()
mux.HandleFunc("/api/", handler)
// Aplicar middleware
http.ListenAndServe(":8080", RateLimitMiddleware(userLimiters)(mux))Comparação de algoritmos (valores de referência):
| Algoritmo | Throughput | Uso de Memória | Recursos |
|---|---|---|---|
| Token Bucket | Alto | Baixo | Suporte a rajada |
| Janela Fixa | Mais Alto | Mais Baixo | Simples |
| Janela Deslizante | Médio | Médio | Preciso |
| Concorrente | Alto | Baixo | Otimizado para concorrência |
# Testar rate limiting de servidor API (1000 req/s, 5 minutos)
go run main.go -server api.example.com:443 -rate 1000 -duration 5m -connections 50# Teste de aumento gradual de carga
for rate in 100 500 1000 2000 5000; do
echo "Testando taxa: $rate req/s"
go run main.go -rate $rate -duration 1m
sleep 10
done# Medição de largura de banda com tamanho grande de mensagem
go run main.go -size 1024 -rate 1000 -protocol udp-
Erro "Too many open files"
# Aumentar limite de descritores de arquivo ulimit -n 65536
-
Erros de conexão em altas taxas
- Ajustar parâmetro
-connections - Verificar tamanhos de buffer do lado servidor
- Ajustar parâmetro
-
Perda de pacotes UDP
- Reduzir taxa ou tamanho de mensagem
- Ajustar tamanho do buffer UDP do kernel
# Compilar cliente
go build -o rate-limit-client main.go
# Compilar servidor
go build -o rate-limit-server server/main.go# Executar testes unitários
go test ./...
# Executar benchmarks
go test -bench=. ./sample/...- Criar novo pacote no diretório
sample/ - Implementar interface
RateLimiter:type RateLimiter interface { Allow() bool AllowN(n int) bool }
- Adicionar testes e benchmarks
Licença MIT
Pull requests são bem-vindos. Para mudanças importantes, por favor abra uma issue primeiro para discutir o que você gostaria de mudar.