コンテキストを使用して Go でリクエスト フロー制限を実装する方法

王林
リリース: 2023-07-21 10:13:23
オリジナル
768 人が閲覧しました

Go でコンテキストを使用してリクエスト フロー制限を実装する方法

Web アプリケーションを開発する場合、サーバーの過負荷や悪意のある攻撃を避けるために、特定のリソースまたはインターフェイスへのアクセス頻度を制限する必要があることがよくあります。 Go 言語では、コンテキストと go キーワードを使用してリクエスト フロー制限を実装できます。

コンテキストとは何ですか?
Go 言語では、コンテキストは関数とゴルーチン間で値を渡すメカニズムです。これは、複数の関数呼び出しチェーン間および異なるゴルーチン間でリクエスト固有の値を渡す方法を提供します。コンテキストは通常​​、リクエスト処理中にリクエスト ID、ユーザー認証情報などのリクエスト コンテキスト情報を渡すために使用されます。

以下では、コンテキストを使用してリクエスト電流制限機能を実装する方法を示します。 golang.org/x/time/rate パッケージを使用してトークン バケット アルゴリズムを実装します。トークン バケット アルゴリズムは、アクセス頻度を制御するために使用されるアルゴリズムです。これは単純なアイデアに基づいています。システムは一定のレートでトークンをバケットに入れます。各リクエストは 1 つのトークンを消費します。バケットにトークンがない場合、後続のリクエストは無効になります。制限されます。

まず、必要なライブラリを導入する必要があります:

import (
    "context"
    "fmt"
    "golang.org/x/time/rate"
    "net/http"
)
ログイン後にコピー

次に、要求された電流制限ルールとトークン バケット インスタンスを保存する構造を定義する必要があります:

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) {
    // 使用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)
    }
}
ログイン後にコピー

最後に、http サーバーを作成し、リクエスト処理関数を設定する必要があります:

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

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

    // 启动服务器
    server.ListenAndServe()
}
ログイン後にコピー

これで、コンテキストを使用して Go でリクエスト フロー制限を実装する機能が完成しました。コンテキストを使用すると、リクエストの処理中にスロットル ルールとトークン バケット インスタンスを簡単に渡すことができます。リクエストが現在の制限しきい値を超えた場合、適切な HTTP ステータス コードとエラー メッセージが返されることがあります。

概要
この記事では、コンテキストを使用して Go 言語でリクエスト電流制限機能を実装する方法を紹介します。コンテキストおよびトークン バケット アルゴリズムを使用すると、特定のリソースまたはインターフェイスへのアクセス頻度を簡単に制限でき、それによってサーバーを悪意のあるリクエストから保護できます。

コード例:

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()
}
ログイン後にコピー

この記事が Go 言語でのリクエスト電流制限関数の実装に役立つことを願っています。もちろん、これは単純な例にすぎず、実際にはより複雑なビジネス ロジックが必要になる場合があります。ただし、基本原則を理解し、コンテキストを使用することで、実際のシナリオに応じて拡張し、最適化することができます。 Go 言語を使用した開発が成功することを祈っています。

以上がコンテキストを使用して Go でリクエスト フロー制限を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート