Rate Limiting em Go: guia para limitar a velocidade de requisições

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Rate Limiting em Go: guia completo para limitar a velocidade de requisições

\n\n

Rate limiting (limitação de velocidade de requisições) é um mecanismo essencial de proteção e gerenciamento de carga em aplicações web modernas e microsserviços. Na linguagem Go (Golang), existem diversas abordagens e bibliotecas para implementar rate limiting, desde as simples até as avançadas. Neste artigo, vamos abordar os conceitos principais, bibliotecas populares e mostrar exemplos de código.

\n\n

O que é Rate Limiting e para que serve?

\n\n

Rate limiting é uma técnica para controlar o número de requisições que um cliente pode enviar em um determinado período de tempo. Os principais objetivos são:

\n\n
    \n
  • Proteção contra ataques DDoS — prevenção de sobrecarga do servidor
  • \n
  • Distribuição justa de recursos — acesso igual para todos os usuários
  • \n
  • Economia de recursos — redução de custos de infraestrutura
  • \n
  • Prevenção de abusos — proteção contra scraping e brute force
  • \n
\n\n

Principais algoritmos de Rate Limiting

\n\n

Existem vários algoritmos clássicos, cada um com suas vantagens:

\n\n
    \n
  • Token Bucket (Balde de Tokens) — o algoritmo mais popular, onde "tokens" são acumulados a uma taxa específica
  • \n
  • Leaky Bucket (Balde Furado) — as requisições são processadas a uma taxa fixa, o excesso é descartado
  • \n
  • Fixed Window (Janela Fixa) — um contador simples de requisições em um intervalo de tempo fixo
  • \n
  • Sliding Window (Janela Deslizante) — mais preciso que o Fixed Window, leva em conta os limites de tempo
  • \n
\n\n

Bibliotecas populares para Rate Limiting em Go

\n\n

1. Biblioteca padrão: golang.org/x/time/rate

\n\n

Esta é uma extensão oficial da equipe Go, que implementa o algoritmo Token Bucket. É leve, simples de usar e ideal para a maioria dos cenários.

\n\n
package main\n\nimport (\n    "fmt"\n    "net/http"\n    "time"\n    "golang.org/x/time/rate"\n)\n\nfunc main() {\n    // Cria um limitador: 2 requisições por segundo, com burst 5\n    limiter := rate.NewLimiter(2, 5)\n\n    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {\n        if !limiter.Allow() {\n            http.Error(w, "Muitas requisições", http.StatusTooManyRequests)\n            return\n        }\n        fmt.Fprintf(w, "OK: %s", time.Now().Format(time.RFC3339))\n    })\n\n    http.ListenAndServe(":8080", nil)\n}
\n\n

2. github.com/ulule/limiter

\n\n

Uma biblioteca mais flexível com suporte a vários armazenamentos (Redis, Memcached, in-memory) e algoritmos. Adequada para sistemas distribuídos.

\n\n
import (\n    "github.com/gin-gonic/gin"\n    "github.com/ulule/limiter/v3"\n    "github.com/ulule/limiter/v3/drivers/store/memory"\n)\n\nfunc main() {\n    // Configuração: 10 requisições por segundo\n    rate := limiter.Rate{\n        Period: 1 * time.Second,\n        Limit:  10,\n    }\n\n    store := memory.NewStore()\n    instance := limiter.New(store, rate)\n\n    r := gin.Default()\n    r.Use(func(c *gin.Context) {\n        key := c.ClientIP()\n        context, err := instance.Get(c.Request.Context(), key)\n        if err != nil {\n            c.AbortWithStatusJSON(500, gin.H{"error": "Erro interno"})\n            return\n        }\n        if context.Reached {\n            c.AbortWithStatusJSON(429, gin.H{"error": "Muitas requisições"})\n            return\n        }\n        c.Next()\n    })\n\n    r.Run(":8080")\n}
\n\n

3. github.com/juju/ratelimit

\n\n

Uma biblioteca simples e confiável da Canonical, baseada no algoritmo Token Bucket. Destaca-se pela API minimalista.

\n\n
import (\n    "github.com/juju/ratelimit"\n    "time"\n)\n\nfunc main() {\n    // Cria um bucket: 100 tokens, recarga de 10 tokens por segundo\n    bucket :=                    

Recommendations