ホームページ  >  記事  >  バックエンド開発  >  Go API に API レート制限を追加する

Go API に API レート制限を追加する

Linda Hamilton
Linda Hamiltonオリジナル
2024-10-07 10:49:30354ブラウズ

Adding API Rate Limiting to Your Go API

皆さん、これまで JWT 認証、データベース接続、ロギング、エラー処理など多くのことを説明してきました。しかし、API にリクエストが殺到し始めたらどうなるでしょうか?制御がなければ、トラフィックが増えると、応答時間が遅くなったり、ダウンタイムが発生したりする可能性があります。 ?

今週、私たちはトラフィックの流れを制御するためにレート制限を実装することでこの問題を解決します。シンプルで効果的な golang.org/x/time/rate パッケージを使用します。後で、私独自の ThrottleX ソリューションの準備ができたら、それをよりスケーラブルなオプションとして統合する方法を説明します。 (最新情報については、私の GitHub (github.com/neelp03/throttlex) をチェックしてください。そこで見つかった問題については、お気軽にコメントしてください o7)

なぜレート制限を行うのか? ?

レート制限は API の用心棒のようなもので、指定された時間枠内にユーザーが実行できるリクエストの数を制御します。これにより、API が過剰になるのを防ぎ、すべてのユーザーがスムーズかつ公平にアクセスできるようになります。レート制限は次の場合に不可欠です:

  • 悪用の防止: 悪意のあるユーザーや過度に熱心なユーザーが API を圧倒するのを防ぎます。
  • 安定性: トラフィックの急増時でも、API の応答性と信頼性を維持します。
  • 公平性: ユーザー間でリソースを平等に共有できるようにします。

ステップ 1: 時間/料金パッケージのインストール

golang.org/x/time/rate パッケージは拡張 Go ライブラリの一部であり、簡単なトークンベースのレート リミッターを提供します。始めるには、インストールする必要があります:


go get golang.org/x/time/rate


ステップ 2: レート リミッターの設定

クライアントが実行できるリクエストの数を制御するレート制限ミドルウェアを作成しましょう。この例では、クライアントを 1 分あたり 5 リクエスト に制限します。


package main

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

// Create a struct to hold each client's rate limiter
type Client struct {
    limiter *rate.Limiter
}

// In-memory storage for clients
var clients = make(map[string]*Client)
var mu sync.Mutex

// Get a client's rate limiter or create one if it doesn't exist
func getClientLimiter(ip string) *rate.Limiter {
    mu.Lock()
    defer mu.Unlock()

    // If the client already exists, return the existing limiter
    if client, exists := clients[ip]; exists {
        return client.limiter
    }

    // Create a new limiter with 5 requests per minute
    limiter := rate.NewLimiter(5, 1)
    clients[ip] = &Client{limiter: limiter}
    return limiter
}


ステップ 3: レート制限ミドルウェアの作成

次に、レート制限に基づいてアクセスを制限するミドルウェアで getClientLimiter 関数を使用してみましょう。


func rateLimitingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ip := r.RemoteAddr
        limiter := getClientLimiter(ip)

        // Check if the request is allowed
        if !limiter.Allow() {
            http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
            return
        }

        next.ServeHTTP(w, r)
    })
}


仕組み:

  1. IP ベースの制限: 各クライアントは IP アドレスによって識別されます。クライアントの IP を確認し、それにレート リミッターを割り当てます。
  2. リクエスト チェック: limiter.Allow() メソッドは、クライアントがレート制限内にあるかどうかをチェックします。一致する場合、リクエストは次のハンドラに進みます。そうでない場合は、429 Too Many Requests で応答します。

ステップ 4: ミドルウェアをグローバルに適用しますか?

次に、レート リミッターを API に接続して、すべてのリクエストが API を通過するようにしましょう。


func main() {
    db = connectDB()
    defer db.Close()

    r := mux.NewRouter()

    // Apply rate-limiting middleware globally
    r.Use(rateLimitingMiddleware)

    // Other middlewares
    r.Use(loggingMiddleware)
    r.Use(errorHandlingMiddleware)

    r.HandleFunc("/login", login).Methods("POST")
    r.Handle("/books", authenticate(http.HandlerFunc(getBooks))).Methods("GET")
    r.Handle("/books", authenticate(http.HandlerFunc(createBook))).Methods("POST")

    fmt.Println("Server started on port :8000")
    log.Fatal(http.ListenAndServe(":8000", r))
}


r.Use(rateLimitingMiddleware) を適用することで、すべての受信リクエストがエンドポイントに到達する前にレート リミッターによってチェックされるようになります。


ステップ 5: レート制限をテストしますか?

サーバーを起動します:


go run main.go


それでは、API にいくつかのリクエストを送信してみましょう。 curl でループを使用すると、複数のリクエストを連続してシミュレートできます。


for i in {1..10}; do curl http://localhost:8000/books; done


制限を1 分あたり 5 リクエストに設定しているため、許可されたレートを超えると、429 Too Many Requests という応答が表示されます。


次は何ですか?

これで、golang.org/x/time/rate によるレート制限が完了し、プレッシャー下でも API の安定性と応答性を維持できます。レート制限は、スケーラブルな API にとって重要なツールですが、ここではほんの表面をなぞっただけです。

ThrottleX の運用準備が整ったら、それを Go API に統合してさらに柔軟性と分散レート制限を実現する方法を示すフォローアップ チュートリアルを投稿する予定です。最新情報については、ThrottleX GitHub リポジトリに注目してください!

来週、API を Docker でコンテナ化して、どこでも実行できるようにする予定です。楽しみに待って、コーディングを楽しんでください! ??

以上がGo API に API レート制限を追加するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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