(v6.3.1)で採用されているしくみについて調べた。ここでは、ある期間において特定のクライアントからのアクセスを一定回数以下に制限することをスロットリングと呼ぶことにする*1。あるAPIにスロットリングをかけるときは、ある期間において経過した時間を計算しながら、その期間中にあるクライアントからエンドポイントに来たアクセスの回数をサーバサイドのキャッシュに記録する必要がある。結論スロットリングしたい期間をperiod(単位は秒)とする。「periodで与えられる期間だけ有効なカウンタ」を作ることができれば、そのカウンタにアクセス回数を記録することで、あるクライアントから上限を超える回数のアクセスが来ているかどうか検証できる。スロットリングが実現できる。特定期間において経過した時間を計算する剰余を使ってタイマーを作ることで実現する。アクセスが来た時点でのUNIX時間t*2を取得する。periodがつねに成り立つ。1の次は0に戻るようなタイマーができる。Rubyで書くと次のようになる。1秒ごとに増加するタイマー。1を繰り返すそして、periodからrの値を引くと、1秒ごとにperiodから数値が減り、1の次は値がperiodに戻るようなタイマーができる。1秒ごとに減少するタイマー。値はperiodから1を繰り返すアクセス回数の記録時に、このタイマーから得られる値ををキャッシュの有効期限として設定することで、その期間における残り時間を表現できる。Rack::Attackでは実装上の理由でタイマーの最大値に1秒のバッファを持たせている*3。特定期間のアクセス回数を記録する除算を使って、特定の期間だけ得られるキーを作り、そのキーを使ってキャッシュにアクセス回数を記録する。periodになる連続した範囲ごとにqの値が同じになる。periodの期間中はつねに同じ値つまり、ある期間の間はqの値が同じになるので、アクセス元の情報とqの組み合わせをその期間のクライアントからのアクセス回数のキーとすると、あるクライアンのある期間におけるアクセス回数データを一意に特定できる。このキャッシュの有効期限を、先ほど計算した有効期限として設定すればよい。以上より、periodで与えられる期間だけ有効なカウンタを作ることができる。このカウンタを利用してスロットリングを実現する。引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。