Rate Limiting em Go (Golang): bibliotecas, padrões e exemplos de implementação

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 (Golang): bibliotecas, padrões e exemplos de implementação



Rate limiting (limitação de velocidade de requisições) é um dos principais mecanismos de proteção e controle de carga em serviços web modernos e arquitetura de microsserviços. No ecossistema Go (Golang), existem várias ferramentas maduras para implementar rate limiting, desde o pacote integrado time até bibliotecas especializadas, como golang.org/x/time/rate. Neste artigo, vamos detalhar como o rate limiting funciona em Go, quais bibliotecas usar e fornecer exemplos práticos de código.



O que é Rate Limiting e para que serve?



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

  • Proteção contra ataques DDoS — prevenir sobrecarga do servidor.
  • Distribuição justa de recursos — limitar clientes "gulosos".
  • Cumprimento de SLA — garantir disponibilidade para todos os usuários.
  • Economia de custos — reduzir a carga em bancos de dados e APIs externas.


Em Go, o rate limiting é implementado usando os algoritmos Token Bucket (balde de tokens) e Leaky Bucket (balde furado). O mais popular é o Token Bucket.



Biblioteca golang.org/x/time/rate



A principal e recomendada biblioteca para rate limiting em Go é golang.org/x/time/rate. Ela implementa o algoritmo Token Bucket e faz parte do conjunto estendido de pacotes Go (sub-repositories).



Instalação:

go get golang.org/x/time/rate


Componentes principais

  • rate.Limiter — o objeto limitador principal.
  • rate.NewLimiter(r rate.Limit, b int) — cria um limitador com taxa r de requisições por segundo e tamanho de balde b.
  • Allow() — verifica se a requisição pode ser executada agora (não bloqueante).
  • Wait(ctx) — bloqueia a execução até que um token esteja disponível (considera o contexto).
  • Reserve() — retorna uma Reservation, permitindo adiar a execução.


Exemplo 1: Rate limiter básico

package main

import ( "fmt" "golang.org/x/time/rate" "time")

func main() { // 2 requisições por segundo, balde de 5 tokens limiter := rate.NewLimiter(2, 5)

for i := 0; i < 10; i++ { if limiter.Allow() { fmt.Printf("Requisição %d executada", i) } else { fmt.Printf("Requisição %d rejeitada (limite)", i) } time.Sleep(200 * time.Millisecond) }}


Exemplo 2: Rate limiter com espera (Wait)

package main

import ( "context" "fmt" "golang.org/x/time/rate" "time")

func main() { limiter := rate.NewLimiter(1, 3) // 1 requisição por segundo, balde de 3 ctx := context.Background()

for i := 0; i < 6; i++ { err := limiter.Wait(ctx) if err != nil { fmt.Println("Erro de espera:", err) return } fmt.Printf("Requisição %d executada em %s", i, time.Now().Format("15:04:05.000")) }}


Implementação de HTTP middleware com rate limiting



Na prática, o rate limiting é mais frequentemente aplicado no nível do servidor HTTP. Vejamos um exemplo de middleware para Gin ou net/http padrão.



package main

import ( "net/http" "golang.org/x/time/rate")

// RateLimiterMiddleware retorna um middleware com rate limitfunc RateLimiterMiddleware(r rate.Limit, b int) func(http.Handler) http.Handler { limiter := rate.NewLimiter(r, b) return func(next http.Handler) http.Handler { return http.HandlerFunc(f

Recommendations