Maison >développement back-end >Golang >Comment utiliser le contexte pour implémenter la limitation du flux de requêtes dans Go

Comment utiliser le contexte pour implémenter la limitation du flux de requêtes dans Go

王林
王林original
2023-07-21 10:13:23774parcourir

Comment utiliser le contexte pour implémenter la limitation du flux de requêtes dans Go

Lors du développement d'applications Web, nous devons souvent limiter la fréquence d'accès à certaines ressources ou interfaces pour éviter une surcharge du serveur ou des attaques malveillantes. Dans le langage Go, nous pouvons utiliser les mots-clés context et go pour implémenter la limitation du flux de requêtes.

Qu'est-ce que le contexte ?
Dans le langage Go, le contexte est un mécanisme de transmission de valeurs entre les fonctions et les Goroutines. Il fournit un moyen de transmettre des valeurs spécifiques à une requête entre plusieurs chaînes d'appels de fonction et entre différents Goroutines. Le contexte est généralement utilisé pour transmettre des informations contextuelles de demande pendant le traitement de la demande, telles que l'ID de la demande, les informations d'authentification de l'utilisateur, etc.

Ci-dessous, nous montrerons comment utiliser le contexte pour implémenter la fonction de limitation de courant de demande. Nous utiliserons le package golang.org/x/time/rate pour implémenter l'algorithme du compartiment à jetons. L'algorithme du bucket de jetons est un algorithme utilisé pour contrôler la fréquence d'accès. Il est basé sur une idée simple : le système met des jetons dans le bucket à un taux fixe. Lorsqu'il n'y a pas de tokens dans le bucket, chaque requête consomme un jeton. sera restreint.

Tout d'abord, nous devons introduire les bibliothèques requises :

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

Ensuite, nous devons définir une structure pour stocker la règle de limitation de débit demandée et l'instance de bucket de jetons :

type RateLimiter struct {
    limiter *rate.Limiter
}

func NewRateLimiter(rateLimiter rate.Limit, burst int) *RateLimiter {
    return &RateLimiter{
        limiter: rate.NewLimiter(rateLimiter, burst),
    }
}

Ensuite, dans la fonction du processeur qui gère la requête, nous peut utiliser le contexte pour limiter la fréquence d'accès aux requêtes :

func (rl *RateLimiter) handleRequest(w http.ResponseWriter, r *http.Request) {
    // 使用context.WithValue方法将RateLimiter的实例存放到context中
    ctx := context.WithValue(r.Context(), "rateLimiter", rl)

    // 检查当前请求是否达到了限流的阈值
    if rl.limiter.Allow() {
        // 允许访问
        fmt.Fprintf(w, "Hello, World!")
    } else {
        // 请求被限制
        http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
    }
}

Enfin, nous devons créer un serveur http et définir la fonction de traitement des requêtes :

func main() {
    // 创建一个令牌桶实例,允许每秒钟产生10个令牌,桶的最大容量为20
    rateLimiter := NewRateLimiter(rate.Every(time.Second), 20)

    // 创建一个http服务器
    server := http.Server{
        Addr:    ":8080",
        Handler: http.HandlerFunc(rateLimiter.handleRequest),
    }

    // 启动服务器
    server.ListenAndServe()
}

Maintenant, nous avons terminé la fonction d'utilisation du contexte pour implémenter la limitation du flux de requêtes dans Go . En utilisant le contexte, vous pouvez facilement transmettre des règles de limitation et des instances de compartiment de jetons pendant le traitement des demandes. Si la demande dépasse le seuil limite actuel, le code d'état HTTP et le message d'erreur appropriés peuvent être renvoyés.

Résumé
Cet article explique comment utiliser le contexte pour implémenter la fonction de limitation de courant de requête dans le langage Go. En utilisant des algorithmes de contexte et de compartiment de jetons, nous pouvons facilement limiter la fréquence d'accès à des ressources ou des interfaces spécifiques, protégeant ainsi le serveur des requêtes malveillantes.

Exemple de code :

package main

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

type RateLimiter struct {
    limiter *rate.Limiter
}

func NewRateLimiter(rateLimiter rate.Limit, burst int) *RateLimiter {
    return &RateLimiter{
        limiter: rate.NewLimiter(rateLimiter, burst),
    }
}

func (rl *RateLimiter) handleRequest(w http.ResponseWriter, r *http.Request) {
    ctx := context.WithValue(r.Context(), "rateLimiter", rl)

    if rl.limiter.Allow() {
        fmt.Fprintf(w, "Hello, World!")
    } else {
        http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
    }
}

func main() {
    rateLimiter := NewRateLimiter(rate.Every(time.Second), 20)

    server := http.Server{
        Addr:    ":8080",
        Handler: http.HandlerFunc(rateLimiter.handleRequest),
    }

    server.ListenAndServe()
}

J'espère que cet article pourra vous aider à implémenter la fonction de limitation de courant de demande en langage Go. Bien entendu, il ne s’agit que d’un exemple simple, et une logique métier plus complexe peut être nécessaire dans la pratique. Cependant, en comprenant les principes de base et en utilisant le contexte, vous pouvez développer et optimiser en conséquence selon des scénarios réels. Je vous souhaite un bon développement en utilisant le langage Go !

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!

Déclaration:
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