golang.org/x/time/rate
レートリミッターを使用します
「golang.org/x/time/rate」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
rate パッケージ
golang.org/x/time/rate は、本番環境で利用できるトークンバケット Limiter を提供します。Go でのレート制限には標準的な選択肢です。
- 実績のある実装です
- Allow、Wait、Reserve メソッドを提供します
- コンテキストに対応しています
Limiter の作成
rate.NewLimiter は、レート(1秒あたりのトークン数)とバーストサイズを受け取ります。rate.Limit は、1秒あたりのイベント数を表す float64 です。
limiter := rate.NewLimiter(rate.Limit(10), 5)rate.Every
1秒あたりのレートではなく間隔で考えたい場合、rate.Every は期間をレートに変換します。200ms ごとに1イベントは、毎秒5イベントと同じです。
limiter := rate.NewLimiter(rate.Every(200*time.Millisecond), 1)Allow
Allow は、今すぐ利用できるトークンがあるかどうかを返します。トークンを消費して true を返すか、すぐに false を返します。超過したリクエストを拒否する場合に使用します。
if !limiter.Allow() {
fmt.Println("rejected: too many requests")
return
}Wait
Wait は、トークンが利用可能になるか、コンテキストがキャンセルされるまでブロックします。処理を破棄せず、一定のペースで実行したい場合に適しています。
if err := limiter.Wait(ctx); err != nil {
return err
}
doWork()Reserve
Reserve は、待機時間を示す Reservation を返します。待機時間を知るには Delay() を呼び出し、処理を続行しない場合は Cancel() を呼び出します。
r := limiter.Reserve()
if !r.OK() {
return
}
time.Sleep(r.Delay())注: 外部パッケージ
rate パッケージは標準ライブラリに含まれていないため、go get golang.org/x/time/rate とモジュールが必要です。このパッケージをインポートするスニペットは説明用であり、ここでインライン実行することはできません。
標準ライブラリによる実行可能な代替例
rate パッケージは外部パッケージであるため、ここでは200msごとに tick を発生させて Wait を再現する、標準ライブラリだけを使ったペーシングループを示します。
package main
import (
"fmt"
"time"
)
func main() {
tick := time.NewTicker(200 * time.Millisecond)
defer tick.Stop()
for i := 0; i < 4; i++ {
<-tick.C
fmt.Println("processed event", i)
}
}実行時の調整
SetLimit と SetBurst を使うと、実行中に制限を変更できます。設定の再読み込みや上流からの429応答を受けて、処理速度を落としたい場合に便利です。
limiter.SetLimit(rate.Limit(20))
limiter.SetBurst(10)クライアントごとのリミッター
クライアントキーから*rate.Limiterへのマップを、ミューテックスで保護して保持します。そのキーへの最初のリクエストでリミッターを作成し、それ以降のリクエストでは再利用します。
func getLimiter(m map[string]*rate.Limiter, key string) *rate.Limiter {
if l, ok := m[key]; ok {
return l
}
l := rate.NewLimiter(rate.Limit(5), 10)
m[key] = l
return l
}HTTPミドルウェア
各リクエストで最初にAllow()を呼び出すよう、ハンドラーをラップします。false の場合は HTTP 429 Too Many Requests を返します。これはサーバー側で行う標準的なレート制限です。
クイックチェック
rateパッケージに関する知識を確認しましょう。
振り返り
golang.org/x/time/rateについて学びました。
- NewLimiter(rate, burst)でバケットを作成する
- rate.Everyで時間間隔をレートに変換する
- Allowは拒否し、Waitはペースを調整し、Reserveは遅延を報告する
- SetLimitとSetBurstで実行時に調整する
- サーバーではクライアントごとのマップとHTTP 429を使用する
よくある質問
「golang.org/x/time/rate」レッスンは無料ですか?
はい。「golang.org/x/time/rate」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「golang.org/x/time/rate」で何を学びますか?
レートリミッターを使用します ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「golang.org/x/time/rate」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- トークンバケットの概念
- golang.org/x/time/rate
- Goroutineのスロットリング
- バックオフとリトライ