Rate Limiting en Go : guide complet de limitation du débit des requêtes
\n\nLe rate limiting (limitation du débit des requêtes) est un mécanisme essentiel de protection et de gestion de la charge dans les applications web modernes et les microservices. En langage Go (Golang), il existe de nombreuses approches et bibliothèques pour implémenter le rate limiting, des plus simples aux plus avancées. Dans cet article, nous allons analyser les concepts fondamentaux, les bibliothèques populaires et présenter des exemples de code.
\n\nQu'est-ce que le Rate Limiting et pourquoi est-il nécessaire ?
\n\nLe rate limiting est une technique de contrôle du nombre de requêtes qu'un client peut envoyer dans un intervalle de temps donné. Objectifs principaux :
\n\n- \n
- Protection contre les attaques DDoS — prévention de la surcharge du serveur \n
- Répartition équitable des ressources — accès égal pour tous les utilisateurs \n
- Économie de ressources — réduction des coûts d'infrastructure \n
- Prévention des abus — protection contre le scraping et le brute force \n
Algorithmes principaux de Rate Limiting
\n\nIl existe plusieurs algorithmes classiques, chacun avec ses avantages :
\n\n- \n
- Token Bucket (Seau à jetons) — l'algorithme le plus populaire, où les "jetons" s'accumulent à une vitesse déterminée \n
- Leaky Bucket (Seau percé) — les requêtes sont traitées à une vitesse fixe, l'excédent est rejeté \n
- Fixed Window (Fenêtre fixe) — simple compteur de requêtes sur un intervalle de temps fixe \n
- Sliding Window (Fenêtre glissante) — plus précis que Fixed Window, prend en compte les limites temporelles \n
Bibliothèques populaires pour le Rate Limiting en Go
\n\n1. Bibliothèque standard : golang.org/x/time/rate
\n\nIl s'agit de l'extension officielle de l'équipe Go, implémentant l'algorithme Token Bucket. Elle est légère, simple à utiliser et idéale pour la plupart des scénarios.
\n\npackage main\n\nimport (\n "fmt"\n "net/http"\n "time"\n "golang.org/x/time/rate"\n)\n\nfunc main() {\n // Créer un limiteur : 2 requêtes par seconde, avec 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, "Trop de requêtes", 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\n2. github.com/ulule/limiter
\n\nBibliothèque plus flexible avec prise en charge de différents stockages (Redis, Memcached, in-memory) et algorithmes. Adaptée aux systèmes distribués.
\n\nimport (\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 // Configuration : 10 requêtes par seconde\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": "Erreur interne"})\n return\n }\n if context.Reached {\n c.AbortWithStatusJSON(429, gin.H{"error": "Trop de requêtes"})\n return\n }\n c.Next()\n })\n\n r.Run(":8080")\n}\n\n3. github.com/juju/ratelimit
\n\nBibliothèque simple et fiable de Canonical, basée sur l'algorithme Token Bucket. Elle se distingue par une API minimaliste.
\n\nimport (\n "github.com/juju/ratelimit"\n "time"\n)\n\nfunc main() {\n // Créer un bucket : 100 jetons, recharge de 10 jetons par seconde\n bucket :=