ホームページ  >  記事  >  バックエンド開発  >  Golang は IP 電流制限を実装します

Golang は IP 電流制限を実装します

王林
王林オリジナル
2023-05-10 09:21:06703ブラウズ

インターネットとモバイル インターネットの急速な発展に伴い、サーバーへの負荷は増大しており、サーバーへのクライアント要求をどのように制限し、サーバーのクラッシュを回避するかが大きな問題となっています。実際のプロジェクトでは、Web サイトの可用性を確保するために、IP リクエストの数を制限する必要があることがよくあります。

ここでは、Golang を使用して IP 電流制限を実装する方法を紹介します。一般に、トークン バケット アルゴリズムを使用して、IP アドレスに基づいた電流制限を実装します。トークン バケット アルゴリズムは、一定期間内に一定数のリクエストの通過を許可し、一定期間内のリクエスト フローを制限するフロー制御アルゴリズムです。

実装の詳細

トークン バケット アルゴリズムは、一定のレートでトークンをバケットに入れます。トークン バケットには容量制限があります。つまり、バケット内のトークンの数が上限を超えないことを意味します。容量。リクエストごとにトークンがバケットから削除されます。バケットにトークンがない場合、リクエストは処理されません。

IP アドレスに基づいて電流制限を実装するには、IP アドレスごとに最大容量と一定速度のトークン バケットを作成する必要があります。リクエストが来ると、トークン バケットからトークンを削除し、バケットにトークンがない場合はリクエストを拒否します。

これに基づいて、IP 電流リミッターを定義できます。

type IPRateLimiter struct {
    limiterBuckets map[string]*rate.Limiter
    mu             *sync.Mutex
    r              rate.Limit
    b              int
}

その中で、limitterBuckets は文字列 IP アドレスをトークン バケットにマッピングするマッピングです。 mu はミューテックス、r はレート リミッターが 1 秒あたりにトークンを配置する速度、b はトークン バケットの容量です。

IP アドレスごとにトークン バケットを作成するために、関数 NewIPRateLimiter:

func NewIPRateLimiter(r rate.Limit, b int) *IPRateLimiter {
    return &IPRateLimiter{
        limiterBuckets: make(map[string]*rate.Limiter),
        mu:             &sync.Mutex{},
        r:              r,
        b:              b,
    }
}

func (i *IPRateLimiter) AddIP(ip string) *rate.Limiter {
    i.mu.Lock()
    defer i.mu.Unlock()

    limiter := rate.NewLimiter(i.r, i.b)
    i.limiterBuckets[ip] = limiter

    return limiter
}

AddIP 関数を使用して、IP アドレスのトークン バケットを作成します。この IP アドレスに対してトークン バケットが作成された場合は既存のトークン バケットが返され、それ以外の場合は新しいトークン バケットが作成されて返されます。

最後に、IP アドレスへのリクエストの数を制限する HTTP ミドルウェアを実装できます。

func (i *IPRateLimiter) Limit(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ip := r.RemoteAddr
        limiter, ok := i.limiterBuckets[ip]
        if !ok {
            limiter = i.AddIP(ip)
        }

        if !limiter.Allow() {
            http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
            return
        }

        next.ServeHTTP(w, r)
    })
}

このミドルウェアにより、指定されたレートと容量でリクエストを通過させることができます。リクエスト数が容量を超えると、HTTP エラー コード 429 (Too Many Requests) が返されます。

完全なコードは次のとおりです:

package main

import (
    "net/http"
    "strconv"
    "sync"

    "golang.org/x/time/rate"
)

type IPRateLimiter struct {
    limiterBuckets map[string]*rate.Limiter
    mu             *sync.Mutex
    r              rate.Limit
    b              int
}

func NewIPRateLimiter(r rate.Limit, b int) *IPRateLimiter {
    return &IPRateLimiter{
        limiterBuckets: make(map[string]*rate.Limiter),
        mu:             &sync.Mutex{},
        r:              r,
        b:              b,
    }
}

func (i *IPRateLimiter) AddIP(ip string) *rate.Limiter {
    i.mu.Lock()
    defer i.mu.Unlock()

    limiter := rate.NewLimiter(i.r, i.b)
    i.limiterBuckets[ip] = limiter

    return limiter
}

func (i *IPRateLimiter) Limit(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ip := r.RemoteAddr
        limiter, ok := i.limiterBuckets[ip]
        if !ok {
            limiter = i.AddIP(ip)
        }

        if !limiter.Allow() {
            http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
            return
        }

        next.ServeHTTP(w, r)
    })
}

func IndexHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("welcome."))
}

func main() {
    limit := rate.Limit(10) // 速率,每秒放入令牌的数量
    capacity := 100        // 容量,桶的大小

    ipRateLimiter := NewIPRateLimiter(limit, capacity)

    http.Handle("/", ipRateLimiter.Limit(http.HandlerFunc(IndexHandler)))

    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        panic(err)
    }
}

この例では、1 秒あたり 10 個のトークンを許可し、バケット容量を 100 に制限します。これは、リミッターは 1 秒あたり最大 10 件のリクエストを処理できますが、同じ IP アドレスへのリクエストが 100 件に達すると失敗することを意味します。同時に、「ようこそ」に応答する単純なハンドラーを定義します。

結論

この記事では、Golang を使用して IP 電流制限を実装し、トークン バケット アルゴリズムを使用して各 IP アドレスのリクエスト レートを制限します。この方法は、シンプルで効果的な電流制限メカニズムを実装でき、Golang で簡単に実装できます。これは、同時実行性の高いネットワーク アプリケーションを作成する場合に非常に役立つテクニックとなります。

以上がGolang は IP 電流制限を実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。