Maison > développement back-end > Golang > Limitation de débit pour les débutants : qu'est-ce que c'est et comment en créer une en Go

Limitation de débit pour les débutants : qu'est-ce que c'est et comment en créer une en Go

Barbara Streisand
Libérer: 2025-01-01 07:58:10
original
578 Les gens l'ont consulté

La limitation de débit est un concept essentiel dans le développement Web et la conception d'API. Cela garantit que les utilisateurs ou les systèmes ne peuvent envoyer qu'un nombre limité de requêtes à un serveur dans un laps de temps spécifique. Dans cet article de blog, nous explorerons ce qu'est la limitation de débit, pourquoi elle est essentielle et comment implémenter un limiteur de débit simple dans Go.

Rate Limiting for Beginners: What It Is and How to Build One in Go

Qu’est-ce que la limitation de débit ?

Imaginez un parc à thème avec des montagnes russes qui ne peuvent accueillir que 10 personnes toutes les 10 minutes. Si plus de 10 personnes tentent de s’inscrire dans ce délai, elles devront attendre. Cette analogie reflète le principe de limitation de débit dans les systèmes logiciels.

En termes techniques, la limitation de débit restreint le nombre de requêtes qu'un client (par exemple, un utilisateur, un appareil ou une adresse IP) peut envoyer à un serveur au cours d'une période prédéfinie. Ça aide :

  1. Prévenir les abus et garantir une utilisation équitable des ressources.
  2. Protégez les serveurs contre la submersion d'un trafic excessif.
  3. Évitez la surutilisation coûteuse d'API ou de services tiers.

Par exemple, une API peut autoriser 100 requêtes par minute et par utilisateur. Si un utilisateur dépasse cette limite, le serveur refuse toute demande supplémentaire jusqu'à ce que la limite soit réinitialisée.

Comment fonctionne la limitation de débit ?

Un moyen courant de mettre en œuvre une limitation de débit consiste à utiliser l'algorithme de compartiment de jetons. Voici comment cela fonctionne :

  1. Un bucket commence avec un nombre fixe de jetons (par exemple, 10).
  2. Chaque requête supprime un jeton du compartiment.
  3. S'il ne reste plus de jetons dans le bucket, la demande est refusée.
  4. Les jetons sont réapprovisionnés à un rythme constant (par exemple, 1 jeton toutes les secondes) jusqu'à ce que le seau soit plein.

Construire un limiteur de débit simple dans Go

Plongeons dans la création d'un limiteur de débit dans Go qui limite chaque client à 3 requêtes par minute.

Étape 1 : Définir la structure du limiteur de débit

Nous utiliserons sync.Mutex pour garantir la sécurité des threads et stocker des informations telles que le nombre de jetons, la capacité maximale et le taux de recharge.

package main

import (
    "sync"
    "time"
)

type RateLimiter struct {
    tokens         float64   // Current number of tokens
    maxTokens      float64   // Maximum tokens allowed
    refillRate     float64   // Tokens added per second
    lastRefillTime time.Time // Last time tokens were refilled
    mutex          sync.Mutex
}

func NewRateLimiter(maxTokens, refillRate float64) *RateLimiter {
    return &RateLimiter{
        tokens:         maxTokens,
        maxTokens:      maxTokens,
        refillRate:     refillRate,
        lastRefillTime: time.Now(),
    }
}
Copier après la connexion
Copier après la connexion

Étape 2 : implémenter la logique de recharge des jetons

Les jetons doivent être réapprovisionnés périodiquement en fonction du temps écoulé depuis la dernière recharge.

func (r *RateLimiter) refillTokens() {
    now := time.Now()
    duration := now.Sub(r.lastRefillTime).Seconds()
    tokensToAdd := duration * r.refillRate

    r.tokens += tokensToAdd
    if r.tokens > r.maxTokens {
        r.tokens = r.maxTokens
    }
    r.lastRefillTime = now
}
Copier après la connexion
Copier après la connexion

Étape 3 : Vérifiez si une demande est autorisée

La méthode Allow déterminera si une demande peut être traitée en fonction des jetons disponibles.

func (r *RateLimiter) Allow() bool {
    r.mutex.Lock()
    defer r.mutex.Unlock()

    r.refillTokens()

    if r.tokens >= 1 {
        r.tokens--
        return true
    }
    return false
}
Copier après la connexion
Copier après la connexion

Étape 4 : Appliquer une limitation de débit par IP

Pour limiter les requêtes par client, nous créerons une carte des adresses IP avec leurs limiteurs de débit respectifs.

type IPRateLimiter struct {
    limiters map[string]*RateLimiter
    mutex    sync.Mutex
}

func NewIPRateLimiter() *IPRateLimiter {
    return &IPRateLimiter{
        limiters: make(map[string]*RateLimiter),
    }
}

func (i *IPRateLimiter) GetLimiter(ip string) *RateLimiter {
    i.mutex.Lock()
    defer i.mutex.Unlock()

    limiter, exists := i.limiters[ip]
    if !exists {
        // Allow 3 requests per minute
        limiter = NewRateLimiter(3, 0.05)
        i.limiters[ip] = limiter
    }

    return limiter
}
Copier après la connexion

Étape 5 : Créer un middleware pour la limitation du débit

Enfin, nous créerons un middleware HTTP qui applique la limite de débit pour chaque client.

package main

import (
    "sync"
    "time"
)

type RateLimiter struct {
    tokens         float64   // Current number of tokens
    maxTokens      float64   // Maximum tokens allowed
    refillRate     float64   // Tokens added per second
    lastRefillTime time.Time // Last time tokens were refilled
    mutex          sync.Mutex
}

func NewRateLimiter(maxTokens, refillRate float64) *RateLimiter {
    return &RateLimiter{
        tokens:         maxTokens,
        maxTokens:      maxTokens,
        refillRate:     refillRate,
        lastRefillTime: time.Now(),
    }
}
Copier après la connexion
Copier après la connexion

Étape 6 : configurer le serveur

Voici comment tout connecter ensemble et tester le limiteur de débit.

func (r *RateLimiter) refillTokens() {
    now := time.Now()
    duration := now.Sub(r.lastRefillTime).Seconds()
    tokensToAdd := duration * r.refillRate

    r.tokens += tokensToAdd
    if r.tokens > r.maxTokens {
        r.tokens = r.maxTokens
    }
    r.lastRefillTime = now
}
Copier après la connexion
Copier après la connexion

Test du limiteur de débit

Démarrez le serveur et testez-le en utilisant curl ou votre navigateur :

func (r *RateLimiter) Allow() bool {
    r.mutex.Lock()
    defer r.mutex.Unlock()

    r.refillTokens()

    if r.tokens >= 1 {
        r.tokens--
        return true
    }
    return false
}
Copier après la connexion
Copier après la connexion
  • Envoyez rapidement 3 demandes : toutes devraient réussir.
  • Envoyez une 4ème demande dans la même minute : vous devriez voir le message Rate Limit Exceeded.
  • Attendez 20 secondes et réessayez : le seau se remplit et les requêtes devraient aboutir.

Code source

Dépôt GitHub

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal