ホームページ バックエンド開発 Golang Redis を使用した Golang API のレート制限

Redis を使用した Golang API のレート制限

Nov 15, 2024 am 04:28 AM

レート制限 を簡単に言うと、ユーザーまたはクライアントが特定の時間枠内で API に対して実行できるリクエストの数を制限する手法です。過去に天気予報やジョーク API にアクセスしようとしたときに、「レート制限を超えました」というメッセージが表示されたことがあるかもしれません。 API をレート制限する理由については多くの議論がありますが、いくつかの重要な議論は、API を公正に使用すること、セキュリティを確保すること、過負荷からリソースを保護することなどです。

このブログでは、Gin フレームワークを使用して Golang で HTTP サーバーを作成し、Redis を使用してエンドポイントにレート制限機能を適用し、一定期間内に IP によってサーバーに対して行われたリクエストの総数を保存します。設定した制限を超える場合は、エラー メッセージが表示されます。

Gin と Redis が何なのかわからない場合のために説明します。 Gin は Golang で書かれた Web フレームワークです。大量のコードを記述せずに、シンプルで高速なサーバーを作成するのに役立ちます。 Redis は、データベースまたはキャッシュ機能として使用できる、メモリ内のキーと値のデータ ストアです。

前提条件

  • Golang、Gin、Redis についての知識
  • Redis インスタンス (Docker またはリモート マシンを使用できます)

さて、始めましょう。

プロジェクトを初期化するには、 go mod init を実行します。たとえば、 go mod init github.com/Pradumnasaraf/go-redis.

次に、Gin Framework を使用して単純な HTTP サーバーを作成し、それにレート制限のロジックを適用します。以下のコードをコピーできます。とても基本的なことです。 /message エンドポイントに到達すると、サーバーはメッセージで応答します。

以下のコードをコピーした後、 go mod tiny を実行して、インポートしたパッケージを自動的にインストールします。

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/message", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "You can make more requests",
        })
    })
    r.Run(":8081") //listen and serve on localhost:8081
} 
ログイン後にコピー
ログイン後にコピー

ターミナルで go run main.go を実行すると、サーバーを実行でき、ターミナルにこのメッセージが表示されます。

Rate Limiting a Golang API using Redis

テストするには、localhost:8081/message に移動します。ブラウザにこのメッセージが表示されます。

Rate Limiting a Golang API using Redis

サーバーが稼働しているので、/message ルートにレート制限機能を設定しましょう。 go-redis/redis_rate パッケージを使用します。このパッケージの作成者のおかげで、制限を処理およびチェックするためのロジックを最初から作成する必要はありません。面倒な作業はすべてやってくれます。

以下は、レート制限機能を実装した後の完全なコードです。私たちはそれを一つ一つ理解していきます。混乱を避け、さまざまな部分がどのように連携するかを理解するために、完全なコードを早めに提供してください。

コードをコピーしたら、go mod tinyを実行して、インポートされたパッケージをすべてインストールします。それでは、コードを理解してみましょう (コード スニペットの下)。

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/message", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "You can make more requests",
        })
    })
    r.Run(":8081") //listen and serve on localhost:8081
} 
ログイン後にコピー
ログイン後にコピー

まず、rateLimiter() 関数に直接ジャンプして、それを理解しましょう。この関数は、メイン関数の c.ClientIP() を介して取得できるリクエストの IP アドレスである引数を要求します。そして、制限に達した場合はエラーを返し、それ以外の場合は nil のままにします。コードの大部分は、公式 GitHub リポジトリから取得した定型コードです。ここで詳しく調べる重要な機能は、limitter.Allow() 関数です。 Addr: Redis インスタンスの URL パス値を取得します。 Dockerを使用してローカルで実行しています。何でも使用できますが、URL は適宜置き換えてください。

package main

import (
    "context"
    "errors"
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/go-redis/redis_rate/v10"
    "github.com/redis/go-redis/v9"
)

func main() {
    r := gin.Default()
    r.GET("/message", func(c *gin.Context) {
        err := rateLimiter(c.ClientIP())
        if err != nil {
            c.JSON(http.StatusTooManyRequests, gin.H{
                "message": "you have hit the limit",
            })
            return
        }
        c.JSON(http.StatusOK, gin.H{
            "message": "You can make more requests",
        })
    })
    r.Run(":8081")
}

func rateLimiter(clientIP string) error {
    ctx := context.Background()
    rdb := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    })

    limiter := redis_rate.NewLimiter(rdb)
    res, err := limiter.Allow(ctx, clientIP, redis_rate.PerMinute(10))
    if err != nil {
        panic(err)
    }
    if res.Remaining == 0 {
        return errors.New("Rate")
    }

    return nil
}
ログイン後にコピー

これは 3 つの引数を取ります。最初の引数は ctx で、2 番目の引数は Redis データベースの Key、Key (値のキー)、そして 3 番目の引数は制限です。したがって、この関数は clientIP アドレスをキーとして、デフォルトの制限を値として保存し、リクエストが行われたときに制限を減らします。この構造の理由は、Redis データベースにはキーと値のペアの種類のデータを保存するための一意の識別と一意のキーが必要であり、すべての IP アドレスは独自の方法で一意であるためです。これが、ユーザー名の代わりに IP アドレスを使用している理由です。 3 番目の引数 redis_rate.PerMinute(10) は必要に応じて変更でき、制限 PerSecond を設定できます。 PerHour など、1 分/秒/時間あたりに実行できるリクエストの数を括弧内の値に設定します。私たちの場合、1 分あたり 10 です。はい、設定はとても簡単です。

最後に、res.Remaining によって not の割り当てが残っているかどうかを確認しています。ゼロの場合はメッセージとともにエラーを返します。それ以外の場合は nil を返します。たとえば、 res.Limit.Rate を実行して制限レートなどを確認することもできます。試してみたり、さらに深く掘り下げたりすることができます。

main() 関数が登場します:

res, err := limiter.Allow(ctx, clientIP, redis_rate.PerMinute(10))
ログイン後にコピー

すべてがほぼ同じです。 /message ルートでは、ルートがヒットするたびに rateLimit() 関数を呼び出し、ClientIP アドレスを渡し、戻り値 (エラー) の値を err 変数に格納します。エラーがある場合は、429、つまり http.StatusTooManyRequests と、メッセージ "message": "制限に達しました" を返します。その人に残りの制限があり、rateLimit() がエラーを返さなかった場合、以前と同様に正常に動作し、リクエストが処理されます。

説明は以上です。動作をテストしてみましょう。同じコマンドを実行してサーバーを再実行します。初めて、前に受け取ったのと同じメッセージが表示されます。ここでブラウザを 10 回更新します (1 分あたり 10 回という制限を設定しているため)。ブラウザにエラー メッセージが表示されます。

Rate Limiting a Golang API using Redis

ターミナルのログを見てこれを確認することもできます。 Gin はすぐに使える優れたログ機能を提供します。 1 分後に制限割り当てが復元されます。

Rate Limiting a Golang API using Redis

このブログはこれで終わりです。私がこの記事を書いて楽しんでいるのと同じように、皆さんも読んで楽しんでいただければ幸いです。最後までやり遂げてよかったです。ご支援ありがとうございました。また、Golang や、オープンソースや Docker などのその他のことについても X (Twitter) で定期的に話しています。あそこに繋いでもらえますよ。

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

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Golang vs. Python:パフォーマンスとスケーラビリティ Golang vs. Python:パフォーマンスとスケーラビリティ Apr 19, 2025 am 12:18 AM

Golangは、パフォーマンスとスケーラビリティの点でPythonよりも優れています。 1)Golangのコンピレーションタイプの特性と効率的な並行性モデルにより、高い並行性シナリオでうまく機能します。 2)Pythonは解釈された言語として、ゆっくりと実行されますが、Cythonなどのツールを介してパフォーマンスを最適化できます。

Golang and C:Concurrency vs. Raw Speed Golang and C:Concurrency vs. Raw Speed Apr 21, 2025 am 12:16 AM

Golangは並行性がCよりも優れていますが、Cは生の速度ではGolangよりも優れています。 1)Golangは、GoroutineとChannelを通じて効率的な並行性を達成します。これは、多数の同時タスクの処理に適しています。 2)Cコンパイラの最適化と標準ライブラリを介して、極端な最適化を必要とするアプリケーションに適したハードウェアに近い高性能を提供します。

ゴーを始めましょう:初心者のガイド ゴーを始めましょう:初心者のガイド Apr 26, 2025 am 12:21 AM

goisidealforforbeginnersandsutable forcloudnetworkservicesduetoitssimplicity、andconcurrencyfeatures.1)installgofromtheofficialwebsiteandverify with'goversion'.2)

Golang vs. C:パフォーマンスと速度の比較 Golang vs. C:パフォーマンスと速度の比較 Apr 21, 2025 am 12:13 AM

Golangは迅速な発展と同時シナリオに適しており、Cは極端なパフォーマンスと低レベルの制御が必要なシナリオに適しています。 1)Golangは、ごみ収集と並行機関のメカニズムを通じてパフォーマンスを向上させ、高配列Webサービス開発に適しています。 2)Cは、手動のメモリ管理とコンパイラの最適化を通じて究極のパフォーマンスを実現し、埋め込みシステム開発に適しています。

Golangの影響:速度、効率、シンプルさ Golangの影響:速度、効率、シンプルさ Apr 14, 2025 am 12:11 AM

speed、効率、およびシンプル性をspeedsped.1)speed:gocompilesquilesquicklyandrunseffictient、理想的なlargeprojects.2)効率:等系dribribraryreducesexexternaldedenciess、開発効果を高める3)シンプルさ:

Golang vs. Python:重要な違​​いと類似点 Golang vs. Python:重要な違​​いと類似点 Apr 17, 2025 am 12:15 AM

GolangとPythonにはそれぞれ独自の利点があります。Golangは高性能と同時プログラミングに適していますが、PythonはデータサイエンスとWeb開発に適しています。 Golangは同時性モデルと効率的なパフォーマンスで知られていますが、Pythonは簡潔な構文とリッチライブラリエコシステムで知られています。

GolangとC:パフォーマンスのトレードオフ GolangとC:パフォーマンスのトレードオフ Apr 17, 2025 am 12:18 AM

GolangとCのパフォーマンスの違いは、主にメモリ管理、コンピレーションの最適化、ランタイム効率に反映されています。 1)Golangのゴミ収集メカニズムは便利ですが、パフォーマンスに影響を与える可能性があります。

パフォーマンスレース:ゴラン対c パフォーマンスレース:ゴラン対c Apr 16, 2025 am 12:07 AM

GolangとCにはそれぞれパフォーマンス競争において独自の利点があります。1)Golangは、高い並行性と迅速な発展に適しており、2)Cはより高いパフォーマンスと微細な制御を提供します。選択は、プロジェクトの要件とチームテクノロジースタックに基づいている必要があります。

See all articles