Welcome to eazy code

Hi there 👋

goでレートリミットを実装してみた

はじめに 先日とある API 関連の本を読んでいたときに、レートリミットについて触れている箇所がありました。 それを読んでいて、ふと「自分でレートリミットの実装をしたことないなぁ」「Go でどうやってレートリミットを実装するんだろう」と思ったので、この記事では golang.org/x/time/rate を使ってレートリミットを実装してみたことをまとめます。 システムの安定性を保つためには、外部からのリクエスト数を適切に制御することが重要です。この記事が、Go で API サーバーなどを開発している人の参考になれば幸いです。 golang.org/x/time/rate とは golang.org/x/time/rate は、準標準パッケージの一つで、トークンバケット (Token Bucket) と呼ばれるアルゴリズムに基づいたレートリミッターを提供します。 なぜレートリミットが必要か? 外部に公開している API サーバーなどのシステムを運用する上で、以下のような理由からレートリミットは不可欠です。 過負荷からの保護: 特定のユーザーやクライアントからの大量リクエストによるサーバーダウンを防ぎます。 公平なリソース分配: 全てのユーザーが安定してサービスを利用できるよう、リソースを公平に分配します。 悪意のある攻撃の緩和: ブルートフォース攻撃や DDoS 攻撃のような、短時間に大量のリクエストを送る攻撃を緩和します。 トークンバケットアルゴリズムの仕組み rateパッケージを理解するために、トークンバケットの概念について説明します。これは「トークンが入ったバケツ」に例えることができます。 バケツ (Bucket): リクエストを処理する権利である「トークン」を貯めておく場所です。このバケツの容量が burst (バースト) 量にあたります。 トークンの補充 (Refill): バケツには、一定のペースで新しいトークンが補充されます。この補充される速さが rate (レート) です。 リクエストの処理 (Consume): リクエストが 1 つ来るたびに、バケツからトークンを 1 つ消費します。 もしリクエストが来たときにバケツにトークンがあれば、即座にリクエストは許可されます。しかし、トークンが空っぽの場合、新しいトークンが補充されるまで待つか、リクエストを諦める(拒否する)しかありません。 この仕組みの優れた点は、平均レートを制御しつつ、一時的なリクエストの集中(バースト)にも対応できることです。 rate.Limit (レート): 1 秒あたりにバケツに補充されるトークンの数です。これにより、長期的に見た場合の平均リクエストレートが決定されます。例えば rate.Limit(10) であれば、1 秒間に 10 個のペースでトークンが補充されます。 burst (バースト): バケツの最大容量です。普段リクエストが少なくトークンが貯まっている状態であれば、最大でこの burst 数まで、レートを超えた連続リクエストを即座に処理できます。これにより、アプリケーションの応答性を損なわずに、突発的なトラフィックをさばくことが可能になります。 インストール まずはパッケージをインストールします。 ...

November 27, 2025 · 3 min

Hello World

November 27, 2025 · 0 min